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_mode.hpp"
8#include "style_sheet.hpp"
9#include "style_sheet_parser.hpp"
10#include "../log.hpp"
11#include "../trace.hpp"
12#include "../file/glob.hpp"
13#include <limits>
14#include <vector>
15#include <memory>
16#include <filesystem>
17
18namespace hi { inline namespace v1 {
19namespace detail {
20
25public:
26 [[nodiscard]] inline static theme_book& global() noexcept;
27
28 ~theme_book() = default;
29 theme_book(theme_book const&) = delete;
30 theme_book(theme_book&&) = delete;
31 theme_book& operator=(theme_book const&) = delete;
32 theme_book& operator=(theme_book&&) = delete;
33 theme_book() = default;
34
35 void register_theme_directory(std::filesystem::path const& path) noexcept
36 {
37 theme_dirs.push_back(path);
38 refresh();
39 }
40
43 void refresh()
44 {
45 theme_files.clear();
46
47 for (hilet& theme_dir : theme_dirs) {
48 hilet theme_dir_glob = theme_dir / "**" / "*.css";
49 for (hilet& path : glob(theme_dir_glob)) {
50 try {
51 auto style_sheet = hi::parse_style_sheet(path);
52 hi_log_info("Found theme {}:{} at '{}'.", style_sheet.name, style_sheet.mode, path.generic_string());
53
54 theme_files.emplace_back(style_sheet.name, style_sheet.mode, path);
55
56 } catch (std::exception const& e) {
57 hi_log_error("Unable to load theme from file '{}': {}", path.generic_string(), e.what());
58 }
59 }
60 }
61 }
62
69 [[nodiscard]] std::vector<std::string> names() const noexcept
70 {
72
73 for (hilet& theme_file : theme_files) {
74 names.push_back(theme_file.name);
75 }
76
78 hilet new_end = std::unique(names.begin(), names.end());
79 names.erase(new_end, names.cend());
80 return names;
81 }
82
89 [[nodiscard]] std::optional<std::filesystem::path> find(std::string name, theme_mode mode) const noexcept
90 {
91 // First find the exact match.
92 auto it = find_if(theme_files.begin(), theme_files.end(), [&](hilet& entry) {
93 return entry.name == name and entry.mode == mode;
94 });
95
96 if (it != theme_files.end()) {
97 return it->path;
98 }
99
100 // Next find the theme for different modes..
101 it = find_if(theme_files.begin(), theme_files.end(), [&](hilet& entry) {
102 return entry.name == name;
103 });
104
105 if (it != theme_files.end()) {
106 return it->path;
107 }
108
109 return std::nullopt;
110 }
111
112private:
113 struct theme_file_entry {
114 std::string name;
115 hi::theme_mode mode;
116 std::filesystem::path path;
117 };
118
121};
122
123[[nodiscard]] inline theme_book& theme_book::global() noexcept
124{
125 static auto r = theme_book{};
126 return r;
127}
128
129} // namespace detail
130
131inline void register_theme_directory(std::filesystem::path const& path) noexcept
132{
133 return detail::theme_book::global().register_theme_directory(path);
134}
135
142[[nodiscard]] inline std::vector<std::string> theme_names() noexcept
143{
144 return detail::theme_book::global().names();
145}
146
153inline bool load_theme(std::string name, theme_mode mode) noexcept
154{
155 if (hilet path = detail::theme_book::global().find(name, mode)) {
156 try {
157 parse_style_sheet(*path).activate();
158 hi_log_info("Theme {} at '{}' activated successfully.", name, path->generic_string());
159 return true;
160
161 } catch (std::exception const& e) {
162 hi_log_error("Unable to load theme {} from file '{}': {}", name, path->generic_string(), e.what());
163 return false;
164 }
165
166 } else {
167 hi_log_error("Unable to find a theme matching {}:{}", name, mode);
168 return false;
169 }
170}
171
172}} // namespace hi::v1
Defines utilities for handling glob patterns.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
generator< std::filesystem::path > glob(glob_pattern pattern)
Find paths on the filesystem that match the glob pattern.
Definition glob.hpp:875
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
std::vector< std::string > theme_names() noexcept
Get a list of theme names.
Definition theme_book.hpp:142
bool load_theme(std::string name, theme_mode mode) noexcept
Find a theme matching the name and mode.
Definition theme_book.hpp:153
Definition style_sheet.hpp:223
theme_book keeps track of multiple themes.
Definition theme_book.hpp:24
void refresh()
Refresh the list of themes from the theme directories.
Definition theme_book.hpp:43
std::vector< std::string > names() const noexcept
Get a list of theme names.
Definition theme_book.hpp:69
std::optional< std::filesystem::path > find(std::string name, theme_mode mode) const noexcept
Find a theme matching the name and mode.
Definition theme_book.hpp:89
T begin(T... args)
T clear(T... args)
T emplace_back(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)