395{
397 if (!n)
398 return;
399
400 ImGuiIO& io = ImGui::GetIO();
401 const bool windowFocused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootAndChildWindows);
402 if (windowFocused && io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_S, false))
404
405 if (ImGui::Button(n->open_editor ? "Hide Editor" : "Show Editor"))
407 ImGui::SameLine();
408 if (ImGui::Button("Save"))
410 ImGui::SameLine();
411 if (ImGui::Button("Delete"))
412 {
415 return;
416 }
417 ImGui::SameLine();
418 ImGui::TextDisabled("%s", n->saved_locally ? n->file_path.filename().string().c_str() : "(unsaved)");
419 ImGui::Separator();
420
421 const float spacing = ImGui::GetStyle().ItemSpacing.x;
422 const float splitterW = 6.f;
423
424 float editorW = 0.f, viewerW = 0.f;
425 if (n->open_editor)
426 {
427 const float shared = availW - splitterW - spacing;
428 editorW = floorf(shared * 0.5f);
429 viewerW = shared - editorW;
430 }
431 else
432 {
433 viewerW = availW;
434 }
435
436
437 if (n->open_editor)
438 {
439 ImGui::BeginChild("##editor", ImVec2(editorW, 0.f), true);
441 if (!ts.bufferInit)
442 {
443 ts.editBuffer = n->markdown_text;
444 ts.bufferInit = true;
445 }
446
447 ImVec2 editorSize = ImGui::GetContentRegionAvail();
448 float wrap_px = editorSize.x - ImGui::GetStyle().FramePadding.x * 2.0f;
449
450
452 &ts.editBuffer,
453 editorSize,
454 wrap_px,
455 ImGuiInputTextFlags_AllowTabInput);
457 ImGui::EndChild();
458
459 ImGui::SameLine();
460 ImGui::InvisibleButton("##split2", ImVec2(splitterW, 0.f));
461 ImGui::SameLine();
462 }
463
464
465 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
466 ImGui::BeginChild("##viewer", ImVec2(viewerW, 0.f), true);
467 {
469 ImGui::TextDisabled("Author: %s", n->author.c_str());
470 ImGui::SameLine();
471 ImGui::TextDisabled("Created: %lld", (long long)toMs(n->creation_ts));
472 ImGui::SameLine();
473 ImGui::TextDisabled("Updated: %lld", (long long)toMs(n->last_update_ts));
474 ImGui::Separator();
475
476
477 md_.
onRoll = [
this](
const std::string& expr)
478 {
481
482
483 };
485 {
487 };
490
491 const std::string& md = n->open_editor ?
tabState_[uuid].editBuffer : n->markdown_text;
492
493 ImGui::PushTextWrapPos(0.f);
494 if (!md.empty())
495 md_.print(md.c_str(), md.c_str() + md.size());
496 else
497 ImGui::TextDisabled("(empty)");
498 ImGui::PopTextWrapPos();
499 }
500 ImGui::EndChild();
501 ImGui::PopStyleVar();
502
503
504 if (n->open_editor)
505 {
507 if (ts.bufferInit && ts.editBuffer != n->markdown_text)
509 }
510}
static bool InputTextMultilineString_HardWrap(const char *label, std::string *str, const ImVec2 &size, float max_px_line, ImGuiInputTextFlags flags=0)
std::function< std::string(const std::string &ref) resolveNoteRef)
std::function< void(const std::string &expr) onRoll)
std::function< void(const std::string &uuid) onNoteOpen)
void actSaveNote_(const std::string &uuid)
std::shared_ptr< ChatManager > chat_manager
void toggleOpenEditor_(const std::string &uuid)
bool openTabByUuid(const std::string &uuid)
static int64_t toEpochMillis(std::chrono::system_clock::time_point tp)