diff options
Diffstat (limited to 'src/rttt/view.hpp')
-rw-r--r-- | src/rttt/view.hpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/rttt/view.hpp b/src/rttt/view.hpp new file mode 100644 index 0000000..3228cd3 --- /dev/null +++ b/src/rttt/view.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "nlohmann/json.hpp" + +#include "storage.hpp" + +namespace rttt { +namespace view { + +enum class layout : int { base = 1, text = 2, numbering = 4, spacing = 8 }; + +inline layout &operator|=(layout &a, layout b) { + return (layout &)((int &)a |= (int)b); +} +inline layout operator|(layout a, layout b) { + return (layout)((int)a | (int)b); +} +inline layout &operator^=(layout &a, layout b) { + return (layout &)((int &)a ^= (int)b); +} +inline layout operator^(layout a, layout b) { + return (layout)((int)a ^ (int)b); +} +inline layout operator&(layout a, layout b) { + return (layout)((int)a & (int)b); +} +inline layout operator&=(layout &a, layout b) { + return (layout &)((int &)a &= (int)b); +} +inline bool operator==(layout a, layout b) { return (int)(a & b) != 0; } +inline bool operator!=(layout a, layout b) { return !(a == b); } + +struct item_state { + bool collapsed = false; + bool read = false; +}; + +void to_json(nlohmann::json &j, const item_state &s) { + j = nlohmann::json{{"collapsed", s.collapsed}, {"read", s.read}}; +} + +void from_json(const nlohmann::json &j, item_state &s) { + j.at("collapsed").get_to(s.collapsed); + j.at("read").get_to(s.read); +} + +bool is_collapsed(const rttt::active_storage<std::string, item_state> &state, + const std::string &id) { + if (state.contains(id)) + return state.at(id).collapsed; + return false; +} + +bool is_read(const rttt::active_storage<std::string, item_state> &state, + const std::string &id) { + if (state.contains(id)) + return state.at(id).read; + return false; +} + +rttt::active_storage<std::string, item_state> +toggle_collapsed(rttt::active_storage<std::string, item_state> &&state, + const std::string &id) { + if (state.contains(id)) { + auto &v = state.at(id); + v.collapsed = !v.collapsed; + if (v.read == false && v.collapsed == false) + state.erase(id); + } else { + state.insert({id, item_state{true, false}}); + } + return state; +} + +rttt::active_storage<std::string, item_state> +toggle_read(rttt::active_storage<std::string, item_state> &&state, + const std::string &id) { + if (state.contains(id)) { + auto &v = state.at(id); + v.read = !v.read; + if (v.read == false && v.collapsed == false) + state.erase(id); + } else { + state.insert({id, item_state{false, true}}); + } + return state; +} + +rttt::active_storage<std::string, item_state> +mark_read(rttt::active_storage<std::string, item_state> &&state, + const std::string &id) { + if (!is_read(state, id)) + return toggle_read(std::move(state), id); + return std::move(state); +} +} // namespace view +} // namespace rttt |