modding simple imgui text editor
This commit is contained in:
parent
95a037ea35
commit
b5de74578a
17
external/CMakeLists.txt
vendored
17
external/CMakeLists.txt
vendored
@ -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
|
||||||
|
@ -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());
|
||||||
|
@ -24,6 +24,7 @@ target_link_libraries(solanaceae_crdtnotes_imgui PUBLIC
|
|||||||
#imgui_interface
|
#imgui_interface
|
||||||
imgui
|
imgui
|
||||||
#solanaceae_util
|
#solanaceae_util
|
||||||
|
solanaceae_contact
|
||||||
)
|
)
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user