modding simple imgui text editor

This commit is contained in:
Green Sky 2023-11-03 01:22:01 +01:00
parent 95a037ea35
commit b5de74578a
No known key found for this signature in database
6 changed files with 135 additions and 10 deletions

View File

@ -52,6 +52,23 @@ if (NOT TARGET imgui)
#FetchContent_MakeAvailable(imgui) #FetchContent_MakeAvailable(imgui)
endif() endif()
# TODO: move entt dep into solanaceae_contact
if (NOT TARGET EnTT::EnTT)
FetchContent_Declare(EnTT
GIT_REPOSITORY https://github.com/skypjack/entt.git
GIT_TAG v3.12.2
)
FetchContent_MakeAvailable(EnTT)
endif()
if (NOT TARGET solanaceae_contact)
FetchContent_Declare(solanaceae_contact
GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_contact.git
GIT_TAG master
)
FetchContent_MakeAvailable(solanaceae_contact)
endif()
if (NOT TARGET solanaceae_plugin) if (NOT TARGET solanaceae_plugin)
FetchContent_Declare(solanaceae_plugin FetchContent_Declare(solanaceae_plugin
GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_plugin.git GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_plugin.git

View File

@ -31,11 +31,13 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
//ConfigModelI* conf = nullptr; //ConfigModelI* conf = nullptr;
CRDTNotes* crdtn = nullptr; CRDTNotes* crdtn = nullptr;
Contact3Registry* cr = nullptr;
ImGuiContext* imguic = nullptr; ImGuiContext* imguic = nullptr;
{ // make sure required types are loaded { // make sure required types are loaded
//conf = RESOLVE_INSTANCE(ConfigModelI); //conf = RESOLVE_INSTANCE(ConfigModelI);
crdtn = RESOLVE_INSTANCE(CRDTNotes); crdtn = RESOLVE_INSTANCE(CRDTNotes);
cr = RESOLVE_INSTANCE(Contact3Registry);
imguic = RESOLVE_INSTANCE(ImGuiContext); imguic = RESOLVE_INSTANCE(ImGuiContext);
//if (conf == nullptr) { //if (conf == nullptr) {
@ -48,6 +50,11 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
return 2; return 2;
} }
if (cr == nullptr) {
std::cerr << "PLUGIN CRDTNIMGUI missing Contact3Registry\n";
return 2;
}
if (imguic == nullptr) { if (imguic == nullptr) {
std::cerr << "PLUGIN CRDTNIMGUI missing ImGuiContext\n"; std::cerr << "PLUGIN CRDTNIMGUI missing ImGuiContext\n";
return 2; return 2;
@ -58,7 +65,7 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
// static store, could be anywhere tho // static store, could be anywhere tho
// construct with fetched dependencies // construct with fetched dependencies
g_crdtn_imgui = std::make_unique<CRDTNotesImGui>(*crdtn); g_crdtn_imgui = std::make_unique<CRDTNotesImGui>(*crdtn, *cr);
// register types // register types
PROVIDE_INSTANCE(CRDTNotesImGui, "CRDTNotesImGui", g_crdtn_imgui.get()); PROVIDE_INSTANCE(CRDTNotesImGui, "CRDTNotesImGui", g_crdtn_imgui.get());

View File

@ -24,6 +24,7 @@ target_link_libraries(solanaceae_crdtnotes_imgui PUBLIC
#imgui_interface #imgui_interface
imgui imgui
#solanaceae_util #solanaceae_util
solanaceae_contact
) )
######################################## ########################################

View File

@ -28,14 +28,17 @@ struct std::hash<ID32> {
}; };
class CRDTNotes { class CRDTNotes {
public:
using CRDTAgent = ID32; using CRDTAgent = ID32;
using DocID = ID32; using DocID = ID32;
using Doc = GreenCRDT::V3::TextDocument<CRDTAgent>; using Doc = GreenCRDT::V3::TextDocument<CRDTAgent>;
private:
// TODO: add metadata to docs // TODO: add metadata to docs
std::unordered_map<DocID, Doc> _docs; std::unordered_map<DocID, Doc> _docs;
public: public:
// config? // config?
CRDTNotes(void); CRDTNotes(void);
~CRDTNotes(void); ~CRDTNotes(void);

View File

@ -1,8 +1,14 @@
#include "./crdtnotes_imgui.hpp" #include "./crdtnotes_imgui.hpp"
#include <solanaceae/contact/components.hpp>
#include <cstdint> #include <cstdint>
#include <vector>
#include <imgui.h> #include <imgui.h>
#include <misc/cpp/imgui_stdlib.h>
#include <iostream>
namespace detail { namespace detail {
uint8_t nib_from_hex(char c) { uint8_t nib_from_hex(char c) {
@ -40,21 +46,101 @@ namespace detail {
} // detail } // detail
CRDTNotesImGui::CRDTNotesImGui(CRDTNotes& notes) : _notes(notes) { CRDTNotesImGui::CRDTNotesImGui(CRDTNotes& notes, Contact3Registry& cr) : _notes(notes), _cr(cr) {
} }
float CRDTNotesImGui::render(void) { float CRDTNotesImGui::render(void) {
if (_show_global_list) { if (_show_global_list) {
if (ImGui::Begin("CRDTNotes - 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<Contact::Components::TagBig>()) {
if (renderContactListContactSmall(c, false)) {
const auto& self = _cr.get<Contact::Components::Self>(c).self;
_notes.addDoc(
// tox id (id from self)
{},
// random 32bytes?
{}
);
// and open the doc
}
}
ImGui::EndPopup();
}
ImGui::SeparatorText("Global list");
const auto doclist = _notes.getDocList(); const auto doclist = _notes.getDocList();
for (const auto& docid : doclist) { for (const auto& docid : doclist) {
const auto docid_str = detail::to_hex(docid); const auto docid_str = detail::to_hex(docid);
ImGui::TextUnformatted(docid_str.c_str()); //ImGui::TextUnformatted(docid_str.c_str());
if (ImGui::Selectable(docid_str.c_str())) {
// open in editor
_open_docs.emplace(docid);
}
} }
} }
ImGui::End(); ImGui::End();
} }
{
std::vector<CRDTNotes::DocID> 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; return 1.f;
} }
bool CRDTNotesImGui::renderContactListContactSmall(const Contact3 c, const bool selected) const {
std::string label;
label += (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name.c_str() : "<unk>");
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.getDoc(doc_id);
if (doc == nullptr) {
return false;
}
auto text = doc->getText();
if (renderDocText(text)) {
auto op_vec = doc->merge(text);
std::cout << "doc changed " << op_vec.size() << " ops generated\n";
// ... uh?
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);
}

View File

@ -1,15 +1,26 @@
#pragma once #pragma once
#include <solanaceae/crdtnotes/crdtnotes.hpp> #include <solanaceae/crdtnotes/crdtnotes.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <set>
class CRDTNotesImGui { class CRDTNotesImGui {
CRDTNotes& _notes; CRDTNotes& _notes;
Contact3Registry& _cr;
bool _show_global_list {true}; bool _show_global_list {true};
std::set<CRDTNotes::DocID> _open_docs;
public: public:
CRDTNotesImGui(CRDTNotes& notes); CRDTNotesImGui(CRDTNotes& notes, Contact3Registry& cr);
float render(void); float render(void);
bool renderContactListContactSmall(const Contact3 c, const bool selected) const;
bool renderDoc(const CRDTNotes::DocID& doc_id);
bool renderDocText(std::string& text) const;
}; };