HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
theme_book.hpp
1// Copyright Take Vos 2020-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "theme.hpp"
8#include "../settings/settings.hpp"
9#include "../macros.hpp"
10#include <limits>
11#include <vector>
12#include <memory>
13#include <filesystem>
14
15namespace hi::inline v1 {
16
21public:
24 observer<std::string> selected_theme = "default";
25
26 ~theme_book() = default;
27 theme_book(theme_book const&) = delete;
28 theme_book(theme_book&&) = delete;
29 theme_book& operator=(theme_book const&) = delete;
30 theme_book& operator=(theme_book&&) = delete;
31 theme_book() noexcept = default;
32
33 static theme_book& global() noexcept;
34
35 void register_directory(std::filesystem::path path) noexcept
36 {
37 _theme_directories.push_back(path);
38 }
39
40 void reload() noexcept
41 {
42 themes.clear();
43
44 for (hilet& theme_directory : _theme_directories) {
45 hilet theme_directory_glob = theme_directory / "**" / "*.theme.json";
46 for (hilet& theme_path : glob(theme_directory_glob)) {
47 auto t = trace<"theme_scan">{};
48
49 try {
50 themes.push_back(std::make_unique<theme>(theme_path));
51 } catch (std::exception const& e) {
52 hi_log_error("Failed parsing theme at {}. \"{}\"", theme_path.string(), e.what());
53 }
54 }
55 }
56
57 if (ssize(themes) == 0) {
58 hi_log_fatal("Did not load any themes.");
59 }
60 }
61
62 [[nodiscard]] std::vector<std::string> names() const noexcept
63 {
65
66 for (hilet& t : themes) {
67 names.push_back(t->name);
68 }
69
70 std::sort(names.begin(), names.end());
71 hilet new_end = std::unique(names.begin(), names.end());
72 names.erase(new_end, names.cend());
73 return names;
74 }
75
82 [[nodiscard]] theme const& find(std::string_view name, theme_mode mode) const noexcept
83 {
84 theme *default_theme = nullptr;
85 theme *default_theme_and_mode = nullptr;
86 theme *matching_theme = nullptr;
87 theme *matching_theme_and_mode = nullptr;
88
89 for (hilet& t : themes) {
90 if (t->name == name and t->mode == mode) {
91 matching_theme_and_mode = t.get();
92 } else if (t->name == name) {
93 matching_theme = t.get();
94 } else if (t->name == "default" and t->mode == mode) {
95 default_theme_and_mode = t.get();
96 } else if (t->name == "default") {
97 default_theme = t.get();
98 }
99 }
100
101 if (matching_theme_and_mode) {
102 return *matching_theme_and_mode;
103 } else if (matching_theme) {
104 return *matching_theme;
105 } else if (default_theme_and_mode) {
106 return *default_theme_and_mode;
107 } else if (default_theme) {
108 return *default_theme;
109 } else if (ssize(themes) > 0) {
110 return *themes[0].get();
111 } else {
112 hi_no_default();
113 }
114 }
115
116private:
117 inline static std::unique_ptr<theme_book> _global;
118
119 std::vector<std::filesystem::path> _theme_directories;
121};
122
123[[nodiscard]] inline theme_book& theme_book::global() noexcept
124{
125 if (not _global) {
126 _global = std::make_unique<theme_book>();
127 }
128 return *_global;
129}
130
131inline void register_theme_directory(std::filesystem::path const &path) noexcept
132{
133 return theme_book::global().register_directory(path);
134}
135
136inline void reload_themes() noexcept
137{
138 return theme_book::global().reload();
139}
140
141template<std::ranges::range R>
142inline void register_theme_directories(R &&r) noexcept
143{
144 for (auto &path: r) {
145 register_theme_directory(path);
146 }
147 reload_themes();
148}
149
150[[nodiscard]] inline theme const& find_theme(std::string_view name, theme_mode mode) noexcept
151{
152 return theme_book::global().find(name, mode);
153}
154
155[[nodiscard]] inline std::vector<std::string> theme_names() noexcept
156{
157 return theme_book::global().names();
158}
159
160[[nodiscard]] inline theme const &get_selected_theme() noexcept
161{
162 return find_theme(*theme_book::global().selected_theme, os_settings::theme_mode());
163}
164
165} // namespace hi::inline v1
STL namespace.
DOXYGEN BUG.
Definition algorithm.hpp:16
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition theme.hpp:21
theme_book keeps track of multiple themes.
Definition theme_book.hpp:20
theme const & find(std::string_view name, theme_mode mode) const noexcept
Find a theme matching the name and mode.
Definition theme_book.hpp:82
A observer pointing to the whole or part of a observable.
Definition observer.hpp:26
Definition trace.hpp:42
T begin(T... args)
T end(T... args)
T erase(T... args)
T push_back(T... args)
T sort(T... args)
T unique(T... args)
T what(T... args)