#include "./crdtnotes_imgui.hpp" #include #include #include #include #include #include #include namespace detail { uint8_t nib_from_hex(char c) { assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')); if (c >= '0' && c <= '9') { return static_cast(c) - '0'; } else if (c >= 'a' && c <= 'f') { return (static_cast(c) - 'a') + 10u; } else { return 0u; } } char nib_to_hex(uint8_t c) { assert((c & 0xf0) == 0x00); if (/*c >= 0x00 &&*/ c <= 0x09) { return static_cast(c) + '0'; } else if (c >= 0x0a && c <= 0x0f) { return (static_cast(c) + 'a') - 10u; } else { return 0u; } } template std::string to_hex(const Container& data) { std::string res; for (const uint8_t it : data) { res += nib_to_hex(it >> 4); res += nib_to_hex(it & 0x0f); } return res; } } // detail CRDTNotesImGui::CRDTNotesImGui(CRDTNotesSync& notes_sync, Contact3Registry& cr) : _notes_sync(notes_sync), _cr(cr) { } float CRDTNotesImGui::render(void) { if (_show_global_list) { if (ImGui::Begin("CRDTNotes")) { if (ImGui::Button("Create New Doc")) { ImGui::OpenPopup("create new doc contact"); } if (ImGui::BeginPopup("create new doc contact")) { for (const auto& c : _cr.view()) { if (renderContactListContactSmall(c, false)) { //const auto& self = _cr.get(c).self; //assert(_cr.all_of(self)); //const auto& self_id = _cr.get(self); //assert(!self_id.data.empty()); //CRDTNotes::CRDTAgent self_agent_id; //// at most agent size, up to self id size //for (size_t i = 0; i < self_agent_id.size() && i < self_id.data.size(); i++) { //self_agent_id.at(i) = self_id.data.at(i); //} //_notes.addDoc( //// tox id (id from self) //self_agent_id //); _notes_sync.addNewDoc({_cr, c}, false); //// and open the doc } } ImGui::EndPopup(); } ImGui::SeparatorText("Global list"); const auto doclist = _notes_sync.getDocList(); for (const auto& docid : doclist) { const auto docid_str = detail::to_hex(docid); //ImGui::TextUnformatted(docid_str.c_str()); if (ImGui::Selectable(docid_str.c_str())) { // open in editor _open_docs.emplace(docid); } } } ImGui::End(); } { std::vector to_remove; for (const auto& docid : _open_docs) { const std::string docid_str = "Doc " + detail::to_hex(docid); bool open = true; if (ImGui::Begin(docid_str.c_str(), &open)) { renderDoc(docid); } ImGui::End(); if (!open) { to_remove.push_back(docid); } } for (const auto& docid : to_remove) { _open_docs.erase(docid); } } return 1.f; } bool CRDTNotesImGui::renderContactListContactSmall(const Contact3 c, const bool selected) const { std::string label; label += (_cr.all_of(c) ? _cr.get(c).name.c_str() : ""); label += "###"; label += std::to_string(entt::to_integral(c)); return ImGui::Selectable(label.c_str(), selected); } bool CRDTNotesImGui::renderDoc(const CRDTNotes::DocID& doc_id) { auto* doc = _notes_sync.getDoc(doc_id); if (doc == nullptr) { return false; } auto text = doc->getText(); if (renderDocText(text)) { _notes_sync.merge(doc_id, text); return true; } return false; } bool CRDTNotesImGui::renderDocText(std::string& text) const { // TODO: replace with text editor (zep) or visualize stuff?? return ImGui::InputTextMultiline("##doc", &text, {-1,-1}, ImGuiInputTextFlags_AllowTabInput); }