layer strength
This commit is contained in:
@@ -162,6 +162,7 @@ static ImU32 PinColorHovered(Type t)
|
||||
|
||||
static constexpr int PREVIEW_SIZE = 64;
|
||||
static constexpr float PREVIEW_SCALE = 1.5f; // world units per pixel
|
||||
static constexpr float FINAL_PREVIEW_SCALE = 4.0f; // for World Output node
|
||||
|
||||
static GLuint MakePreviewTexture()
|
||||
{
|
||||
@@ -203,8 +204,9 @@ static const std::vector<NodeMenuItem> NODE_MENU = {
|
||||
// ── Source ──────────────────────────────────────────────────────────────
|
||||
{ "Constant", "Source", [] { return std::make_unique<ConstantNode>(0.0f); } },
|
||||
{ "TileID", "Source", [] { return std::make_unique<IDNode>(1); } },
|
||||
{ "PositionX", "Source", [] { return std::make_unique<PositionXNode>(); } },
|
||||
{ "PositionY", "Source", [] { return std::make_unique<PositionYNode>(); } },
|
||||
{ "PositionX", "Source", [] { return std::make_unique<PositionXNode>(); } },
|
||||
{ "PositionY", "Source", [] { return std::make_unique<PositionYNode>(); } },
|
||||
{ "LayerStrength", "Source", [] { return std::make_unique<LayerStrengthNode>(); } },
|
||||
// ── Math ────────────────────────────────────────────────────────────────
|
||||
{ "Add", "Math", [] { return std::make_unique<AddNode>(); } },
|
||||
{ "Subtract", "Math", [] { return std::make_unique<SubtractNode>(); } },
|
||||
@@ -213,6 +215,8 @@ static const std::vector<NodeMenuItem> NODE_MENU = {
|
||||
{ "Modulo", "Math", [] { return std::make_unique<ModuloNode>(); } },
|
||||
{ "Sin", "Math", [] { return std::make_unique<SinNode>(); } },
|
||||
{ "Cos", "Math", [] { return std::make_unique<CosNode>(); } },
|
||||
{ "Floor", "Math", [] { return std::make_unique<FloorNode>(); } },
|
||||
{ "Ceil", "Math", [] { return std::make_unique<CeilNode>(); } },
|
||||
{ "Sqrt", "Math", [] { return std::make_unique<SqrtNode>(); } },
|
||||
{ "Pow", "Math", [] { return std::make_unique<PowNode>(); } },
|
||||
{ "Square", "Math", [] { return std::make_unique<SquareNode>(); } },
|
||||
@@ -245,6 +249,7 @@ static const std::vector<NodeMenuItem> NODE_MENU = {
|
||||
{ "QueryRange", "Query", [] { return std::make_unique<QueryRangeNode>(-1, -1, 1, 1, 1); } },
|
||||
{ "QueryDistance", "Query", [] { return std::make_unique<QueryDistanceNode>(1, 4); } },
|
||||
// ── Noise ───────────────────────────────────────────────────────────────
|
||||
{ "Random", "Noise", [] { return std::make_unique<RandomNode>(); } },
|
||||
{ "PerlinNoise", "Noise", [] { return std::make_unique<PerlinNoiseNode>(0.01f); } },
|
||||
{ "SimplexNoise", "Noise", [] { return std::make_unique<SimplexNoiseNode>(0.01f); } },
|
||||
{ "CellularNoise", "Noise", [] { return std::make_unique<CellularNoiseNode>(0.01f); } },
|
||||
@@ -260,7 +265,6 @@ struct GraphTab {
|
||||
|
||||
Graph graph;
|
||||
std::unordered_map<Graph::NodeID, VisualNode> visualNodes;
|
||||
std::vector<TileEntry> tileRegistry;
|
||||
|
||||
std::vector<Graph::NodeID> worldOutputPasses;
|
||||
GLuint worldOutputTex { 0 };
|
||||
@@ -276,7 +280,6 @@ struct GraphTab {
|
||||
|
||||
void Init()
|
||||
{
|
||||
tileRegistry = { TileEntry{0, "Empty", {30.0f/255.0f, 30.0f/255.0f, 30.0f/255.0f}} };
|
||||
worldOutputPasses = { Graph::INVALID_ID };
|
||||
worldOutputTex = MakePreviewTexture();
|
||||
imnodesCtx = ImNodes::EditorContextCreate();
|
||||
@@ -317,6 +320,10 @@ public:
|
||||
void Render()
|
||||
{
|
||||
// Restore last session written by the ini settings handler.
|
||||
if (!pendingLoadRegistry.empty()) {
|
||||
LoadSharedRegistry(pendingLoadRegistry);
|
||||
pendingLoadRegistry.clear();
|
||||
}
|
||||
if (!pendingLoadFiles.empty()) {
|
||||
for (const auto& f : pendingLoadFiles) {
|
||||
auto& cur = Active();
|
||||
@@ -378,9 +385,16 @@ private:
|
||||
int activeTab { 0 };
|
||||
int requestedTab { -1 }; // set to trigger programmatic tab switch (one frame)
|
||||
|
||||
// Shared tile registry — one across all tabs / graph files
|
||||
std::vector<TileEntry> sharedRegistry {
|
||||
TileEntry{0, "Empty", {30.0f/255.0f, 30.0f/255.0f, 30.0f/255.0f}}
|
||||
};
|
||||
std::string sharedRegistryPath;
|
||||
|
||||
// Pending data from ini settings handler
|
||||
std::vector<std::string> pendingLoadFiles;
|
||||
int pendingActiveTab { -1 };
|
||||
int pendingActiveTab { -1 };
|
||||
std::string pendingLoadRegistry;
|
||||
|
||||
GraphTab& Active() { return tabs[activeTab]; }
|
||||
|
||||
@@ -449,12 +463,12 @@ private:
|
||||
for (int px = 0; px < PREVIEW_SIZE; ++px) {
|
||||
EvalContext ctx;
|
||||
ctx.worldX = tab.previewOriginX + static_cast<int>(px * tab.previewScale);
|
||||
ctx.worldY = tab.previewOriginY + static_cast<int>(py * tab.previewScale);
|
||||
ctx.worldY = tab.previewOriginY + static_cast<int>((PREVIEW_SIZE - 1 - py) * tab.previewScale);
|
||||
ctx.seed = tab.previewSeed;
|
||||
|
||||
Value v = tab.graph.Evaluate(id, ctx);
|
||||
int base = (py * PREVIEW_SIZE + px) * 4;
|
||||
ValueToRGBA(v, &tab.tileRegistry,
|
||||
ValueToRGBA(v, &sharedRegistry,
|
||||
pixels[base], pixels[base+1], pixels[base+2], pixels[base+3]);
|
||||
}
|
||||
}
|
||||
@@ -485,10 +499,10 @@ private:
|
||||
|
||||
for (int py = 0; py < PREVIEW_SIZE; ++py) {
|
||||
for (int px = 0; px < PREVIEW_SIZE; ++px) {
|
||||
int32_t tileID = chunk.Get(tab.previewOriginX + px, tab.previewOriginY + py);
|
||||
int32_t tileID = chunk.Get(tab.previewOriginX + px, tab.previewOriginY + (PREVIEW_SIZE - 1 - py));
|
||||
int base = (py * PREVIEW_SIZE + px) * 4;
|
||||
Value v = Value::MakeInt(tileID);
|
||||
ValueToRGBA(v, &tab.tileRegistry,
|
||||
ValueToRGBA(v, &sharedRegistry,
|
||||
pixels[base], pixels[base+1], pixels[base+2], pixels[base+3]);
|
||||
}
|
||||
}
|
||||
@@ -546,10 +560,27 @@ private:
|
||||
ImGui::Spacing();
|
||||
ImGui::SeparatorText("Tile IDs");
|
||||
|
||||
// Registry file path (read-only display)
|
||||
{
|
||||
const char* rpath = sharedRegistryPath.empty() ? "(unsaved)" : sharedRegistryPath.c_str();
|
||||
ImGui::TextDisabled("%s", rpath);
|
||||
}
|
||||
if (ImGui::SmallButton("Open##reg")) OpenRegistryDialog();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Save##reg"))
|
||||
{
|
||||
if (sharedRegistryPath.empty()) SaveRegistryDialog();
|
||||
else SaveSharedRegistry(sharedRegistryPath);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Save As##reg")) SaveRegistryDialog();
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
int toRemove = -1;
|
||||
for (int i = 0; i < static_cast<int>(tab.tileRegistry.size()); ++i) {
|
||||
for (int i = 0; i < static_cast<int>(sharedRegistry.size()); ++i) {
|
||||
ImGui::PushID(i);
|
||||
TileEntry& entry = tab.tileRegistry[i];
|
||||
TileEntry& entry = sharedRegistry[i];
|
||||
|
||||
// Color button — opens a popup picker.
|
||||
char cpopup[32];
|
||||
@@ -593,11 +624,11 @@ private:
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (toRemove >= 0)
|
||||
tab.tileRegistry.erase(tab.tileRegistry.begin() + toRemove);
|
||||
sharedRegistry.erase(sharedRegistry.begin() + toRemove);
|
||||
|
||||
if (ImGui::SmallButton("+ Add Tile")) {
|
||||
int32_t nextId = tab.tileRegistry.empty() ? 1
|
||||
: tab.tileRegistry.back().id + 1;
|
||||
int32_t nextId = sharedRegistry.empty() ? 1
|
||||
: sharedRegistry.back().id + 1;
|
||||
TileEntry entry;
|
||||
entry.id = nextId;
|
||||
entry.name = "Tile";
|
||||
@@ -608,7 +639,7 @@ private:
|
||||
entry.color[0] = hr / 255.0f;
|
||||
entry.color[1] = hg / 255.0f;
|
||||
entry.color[2] = hb / 255.0f;
|
||||
tab.tileRegistry.push_back(entry);
|
||||
sharedRegistry.push_back(entry);
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
@@ -913,7 +944,7 @@ private:
|
||||
// Generated chunk preview — always 1 tile per pixel.
|
||||
ImGui::Image(
|
||||
static_cast<ImTextureID>(static_cast<uint64_t>(tab.worldOutputTex)),
|
||||
ImVec2(PREVIEW_SIZE * PREVIEW_SCALE, PREVIEW_SIZE * PREVIEW_SCALE));
|
||||
ImVec2(PREVIEW_SIZE * FINAL_PREVIEW_SCALE, PREVIEW_SIZE * FINAL_PREVIEW_SCALE));
|
||||
|
||||
ImNodes::EndNode();
|
||||
|
||||
@@ -986,38 +1017,46 @@ private:
|
||||
return ImGui::DragFloat("##val", &n->value, 0.01f);
|
||||
}
|
||||
|
||||
static bool DrawIDParams(NodeEditorApp& app, Node* node)
|
||||
static bool DrawIDDropdown(const char* label, NodeEditorApp& app, int& currentID)
|
||||
{
|
||||
auto* n = static_cast<IDNode*>(node);
|
||||
auto& reg = app.Active().tileRegistry;
|
||||
auto& reg = app.sharedRegistry;
|
||||
int selIdx = -1;
|
||||
bool changed = false;
|
||||
if (reg.empty()) {
|
||||
changed = ImGui::DragInt("##id", &n->tileID, 1, 0, 9999);
|
||||
} else {
|
||||
int selIdx = -1;
|
||||
for (int i = 0; i < static_cast<int>(reg.size()); ++i)
|
||||
if (reg[i].id == n->tileID) { selIdx = i; break; }
|
||||
const char* preview = selIdx >= 0 ? reg[selIdx].name.c_str() : "???";
|
||||
ImGui::SetNextItemWidth(80);
|
||||
if (ImGui::BeginCombo("##tile", preview)) {
|
||||
for (int i = 0; i < static_cast<int>(reg.size()); ++i) {
|
||||
bool sel = (i == selIdx);
|
||||
char label[80];
|
||||
snprintf(label, sizeof(label), "%s (%d)",
|
||||
reg[i].name.c_str(), reg[i].id);
|
||||
if (ImGui::Selectable(label, sel)) {
|
||||
n->tileID = reg[i].id;
|
||||
changed = true;
|
||||
}
|
||||
if (sel) ImGui::SetItemDefaultFocus();
|
||||
for (int i = 0; i < static_cast<int>(reg.size()); ++i)
|
||||
if (reg[i].id == currentID) { selIdx = i; break; }
|
||||
const char* preview = selIdx >= 0 ? reg[selIdx].name.c_str() : "???";
|
||||
ImGui::SetNextItemWidth(80);
|
||||
if (ImGui::BeginCombo(label, preview)) {
|
||||
for (int i = 0; i < static_cast<int>(reg.size()); ++i) {
|
||||
bool sel = (i == selIdx);
|
||||
char label[80];
|
||||
snprintf(label, sizeof(label), "%s (%d)",
|
||||
reg[i].name.c_str(), reg[i].id);
|
||||
if (ImGui::Selectable(label, sel)) {
|
||||
currentID = reg[i].id;
|
||||
changed = true;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
if (sel) ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawQueryTileParams(NodeEditorApp& /*app*/, Node* node)
|
||||
static bool DrawIDParams(NodeEditorApp& app, Node* node)
|
||||
{
|
||||
auto* n = static_cast<IDNode*>(node);
|
||||
auto& reg = app.sharedRegistry;
|
||||
bool changed = false;
|
||||
if (reg.empty()) {
|
||||
changed = ImGui::DragInt("##id", &n->tileID, 1, 0, 9999);
|
||||
} else {
|
||||
changed |= DrawIDDropdown("##id", app, n->tileID);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawQueryTileParams(NodeEditorApp& app, Node* node)
|
||||
{
|
||||
auto* n = static_cast<QueryTileNode*>(node);
|
||||
bool changed = false;
|
||||
@@ -1028,33 +1067,35 @@ private:
|
||||
changed |= ImGui::DragInt("##oy", &n->offsetY, 1);
|
||||
// TODO: it would be best if this is a dropdown of tile ids that the user can choose from
|
||||
ImGui::Text("Tile ID");
|
||||
changed |= ImGui::DragInt("##eid", &n->expectedID, 1, 0, 1024);
|
||||
changed |= DrawIDDropdown("##eid", app, n->expectedID);
|
||||
ImGui::PopItemWidth();
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawQueryRangeParams(NodeEditorApp& /*app*/, Node* node)
|
||||
static bool DrawQueryRangeParams(NodeEditorApp& app, Node* node)
|
||||
{
|
||||
auto* n = static_cast<QueryRangeNode*>(node);
|
||||
bool changed = false;
|
||||
ImGui::PushItemWidth(70);
|
||||
ImGui::Text("min x -> max x");
|
||||
changed |= ImGui::DragInt("##mnx", &n->minX, 1);
|
||||
ImGui::SameLine();
|
||||
changed |= ImGui::DragInt("##mxx", &n->maxX, 1);
|
||||
ImGui::Text("min y -> max y");
|
||||
changed |= ImGui::DragInt("##mny", &n->minY, 1);
|
||||
ImGui::SameLine();
|
||||
changed |= ImGui::DragInt("##mxy", &n->maxY, 1);
|
||||
changed |= ImGui::DragInt("##rtid", &n->tileID, 1, 0, 1024);
|
||||
changed |= DrawIDDropdown("##rtid", app, n->tileID);
|
||||
ImGui::PopItemWidth();
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DrawQueryDistanceParams(NodeEditorApp& /*app*/, Node* node)
|
||||
static bool DrawQueryDistanceParams(NodeEditorApp& app, Node* node)
|
||||
{
|
||||
auto* n = static_cast<QueryDistanceNode*>(node);
|
||||
bool changed = false;
|
||||
ImGui::PushItemWidth(70);
|
||||
changed |= ImGui::DragInt("##dtid", &n->tileID, 1, 0, 1024);
|
||||
changed |= DrawIDDropdown("##dtid", app, n->tileID);
|
||||
changed |= ImGui::DragInt("##md", &n->maxDistance, 1, 1, 32);
|
||||
ImGui::PopItemWidth();
|
||||
return changed;
|
||||
@@ -1126,6 +1167,75 @@ private:
|
||||
|
||||
// ── Serialization ─────────────────────────────────────────────────────────
|
||||
|
||||
// ── Shared tile registry I/O ──────────────────────────────────────────────
|
||||
|
||||
void SaveSharedRegistry(const std::string& path)
|
||||
{
|
||||
nlohmann::json j;
|
||||
auto& tiles = j["tiles"] = nlohmann::json::array();
|
||||
for (auto& t : sharedRegistry)
|
||||
tiles.push_back({ {"id", t.id}, {"name", t.name},
|
||||
{"color", { t.color[0], t.color[1], t.color[2] }} });
|
||||
std::ofstream f(path);
|
||||
if (f) { f << j.dump(2); sharedRegistryPath = path; }
|
||||
else fprintf(stderr, "Failed to write registry %s\n", path.c_str());
|
||||
}
|
||||
|
||||
void LoadSharedRegistry(const std::string& path)
|
||||
{
|
||||
std::ifstream f(path);
|
||||
if (!f) { fprintf(stderr, "Cannot open registry %s\n", path.c_str()); return; }
|
||||
nlohmann::json j;
|
||||
try { j = nlohmann::json::parse(f); }
|
||||
catch (...) { fprintf(stderr, "JSON parse error in registry %s\n", path.c_str()); return; }
|
||||
|
||||
if (!j.contains("tiles") || !j["tiles"].is_array()) return;
|
||||
|
||||
sharedRegistry.clear();
|
||||
for (auto& t : j["tiles"]) {
|
||||
TileEntry entry;
|
||||
entry.id = t.value("id", 0);
|
||||
entry.name = t.value("name", std::string("Tile"));
|
||||
if (t.contains("color") && t["color"].size() == 3) {
|
||||
entry.color[0] = t["color"][0].get<float>();
|
||||
entry.color[1] = t["color"][1].get<float>();
|
||||
entry.color[2] = t["color"][2].get<float>();
|
||||
}
|
||||
sharedRegistry.push_back(entry);
|
||||
}
|
||||
// Always ensure ID 0 sentinel is present.
|
||||
bool hasEmpty = std::any_of(sharedRegistry.begin(), sharedRegistry.end(),
|
||||
[](const TileEntry& e) { return e.id == 0; });
|
||||
if (!hasEmpty)
|
||||
sharedRegistry.insert(sharedRegistry.begin(),
|
||||
TileEntry{0, "Empty", {30.0f/255.0f, 30.0f/255.0f, 30.0f/255.0f}});
|
||||
|
||||
sharedRegistryPath = path;
|
||||
MarkAllDirty();
|
||||
}
|
||||
|
||||
void OpenRegistryDialog()
|
||||
{
|
||||
IGFD::FileDialogConfig cfg;
|
||||
cfg.path = sharedRegistryPath.empty() ? "."
|
||||
: std::filesystem::path(sharedRegistryPath).parent_path().string();
|
||||
ImGuiFileDialog::Instance()->OpenDialog("OpenRegistryDlg", "Open Tile Registry", ".json", cfg);
|
||||
}
|
||||
|
||||
void SaveRegistryDialog()
|
||||
{
|
||||
IGFD::FileDialogConfig cfg;
|
||||
if (!sharedRegistryPath.empty()) {
|
||||
std::filesystem::path p(sharedRegistryPath);
|
||||
cfg.path = p.parent_path().string();
|
||||
cfg.fileName = p.filename().string();
|
||||
} else {
|
||||
cfg.path = ".";
|
||||
cfg.fileName = "tiles.json";
|
||||
}
|
||||
ImGuiFileDialog::Instance()->OpenDialog("SaveRegistryDlg", "Save Tile Registry", ".json", cfg);
|
||||
}
|
||||
|
||||
void Save(const std::string& path)
|
||||
{
|
||||
auto& tab = Active();
|
||||
@@ -1156,12 +1266,6 @@ private:
|
||||
passes.push_back(id);
|
||||
root["editor"]["worldOutputPasses"] = passes;
|
||||
|
||||
nlohmann::json tiles = nlohmann::json::array();
|
||||
for (auto& t : tab.tileRegistry)
|
||||
tiles.push_back({ {"id", t.id}, {"name", t.name},
|
||||
{"color", { t.color[0], t.color[1], t.color[2] }} });
|
||||
root["editor"]["tileRegistry"] = tiles;
|
||||
|
||||
std::ofstream f(path);
|
||||
if (f) { f << root.dump(2); tab.currentFile = path; }
|
||||
else fprintf(stderr, "Failed to write %s\n", path.c_str());
|
||||
@@ -1188,7 +1292,6 @@ private:
|
||||
tab.worldOutputDirty = true;
|
||||
tab.pendingWorldOutputPos = true;
|
||||
tab.currentFile = "";
|
||||
tab.tileRegistry = { TileEntry{0, "Empty", {30.0f/255.0f, 30.0f/255.0f, 30.0f/255.0f}} };
|
||||
|
||||
tab.graph = std::move(*newGraph);
|
||||
|
||||
@@ -1210,26 +1313,8 @@ private:
|
||||
tab.previewOriginY = ed.value("previewOriginY", 0);
|
||||
tab.previewScale = ed.value("previewScale", 1.0f);
|
||||
|
||||
if (ed.contains("tileRegistry")) {
|
||||
tab.tileRegistry.clear();
|
||||
for (auto& t : ed["tileRegistry"]) {
|
||||
TileEntry entry;
|
||||
entry.id = t.value("id", 0);
|
||||
entry.name = t.value("name", std::string("Tile"));
|
||||
if (t.contains("color") && t["color"].size() == 3) {
|
||||
entry.color[0] = t["color"][0].get<float>();
|
||||
entry.color[1] = t["color"][1].get<float>();
|
||||
entry.color[2] = t["color"][2].get<float>();
|
||||
}
|
||||
tab.tileRegistry.push_back(entry);
|
||||
}
|
||||
// Always guarantee the Empty (ID 0) sentinel is present.
|
||||
bool hasEmpty = std::any_of(tab.tileRegistry.begin(), tab.tileRegistry.end(),
|
||||
[](const TileEntry& e) { return e.id == 0; });
|
||||
if (!hasEmpty)
|
||||
tab.tileRegistry.insert(tab.tileRegistry.begin(),
|
||||
TileEntry{0, "Empty", {30.0f/255.0f, 30.0f/255.0f, 30.0f/255.0f}});
|
||||
}
|
||||
// Note: "tileRegistry" embedded in old .wge files is intentionally
|
||||
// ignored — use the shared tiles.json registry instead.
|
||||
|
||||
if (ed.contains("worldOutputPasses")) {
|
||||
tab.worldOutputPasses.clear();
|
||||
@@ -1320,6 +1405,20 @@ public:
|
||||
Save(ImGuiFileDialog::Instance()->GetFilePathName());
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
|
||||
if (ImGuiFileDialog::Instance()->Display("OpenRegistryDlg",
|
||||
ImGuiWindowFlags_NoCollapse, dlgSize)) {
|
||||
if (ImGuiFileDialog::Instance()->IsOk())
|
||||
LoadSharedRegistry(ImGuiFileDialog::Instance()->GetFilePathName());
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
|
||||
if (ImGuiFileDialog::Instance()->Display("SaveRegistryDlg",
|
||||
ImGuiWindowFlags_NoCollapse, dlgSize)) {
|
||||
if (ImGuiFileDialog::Instance()->IsOk())
|
||||
SaveSharedRegistry(ImGuiFileDialog::Instance()->GetFilePathName());
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void HandleKeyboardShortcuts()
|
||||
@@ -1358,6 +1457,8 @@ public:
|
||||
}
|
||||
if (strncmp(line, "ActiveTab=", 10) == 0)
|
||||
app->pendingActiveTab = std::atoi(line + 10);
|
||||
if (strncmp(line, "SharedRegistry=", 15) == 0)
|
||||
app->pendingLoadRegistry = line + 15;
|
||||
};
|
||||
|
||||
// Called when ImGui writes imgui.ini (periodically and on shutdown).
|
||||
@@ -1370,12 +1471,14 @@ public:
|
||||
files += tab.currentFile;
|
||||
}
|
||||
}
|
||||
out_buf->appendf("[NodeEditor][Session]\n");
|
||||
if (!files.empty()) {
|
||||
out_buf->appendf("[NodeEditor][Session]\n");
|
||||
out_buf->appendf("LastFiles=%s\n", files.c_str());
|
||||
out_buf->appendf("ActiveTab=%d\n", app->activeTab);
|
||||
out_buf->appendf("\n");
|
||||
}
|
||||
if (!app->sharedRegistryPath.empty())
|
||||
out_buf->appendf("SharedRegistry=%s\n", app->sharedRegistryPath.c_str());
|
||||
out_buf->appendf("\n");
|
||||
};
|
||||
|
||||
ImGui::AddSettingsHandler(&h);
|
||||
|
||||
Reference in New Issue
Block a user