Recent projects management + working Link creation

This commit is contained in:
Anthony 2023-12-27 16:03:41 +01:00
parent 15dad50f6c
commit f95495ef6b
10 changed files with 181 additions and 156 deletions

View file

@ -6,7 +6,7 @@
CodeEditor::CodeEditor() CodeEditor::CodeEditor()
: WindowBase("Code editor") : WindowBase("Code editor")
{ {
mEditor.SetReadOnly(true);
} }
void CodeEditor::Initialize() void CodeEditor::Initialize()

View file

@ -147,25 +147,7 @@ void ConsoleWindow::Draw()
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
/*
// Command-line
bool reclaim_focus = false;
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
{
char* s = InputBuf;
Strtrim(s);
if (s[0])
ExecCommand(s);
strcpy(s, "");
reclaim_focus = true;
}
// Auto-focus on window apparition
ImGui::SetItemDefaultFocus();
if (reclaim_focus)
ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
*/
WindowBase::EndDraw(); WindowBase::EndDraw();
} }

View file

@ -41,6 +41,8 @@ MainWindow::MainWindow()
m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback); m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback);
m_story.Clear(); m_story.Clear();
CloseProject();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -62,27 +64,6 @@ std::string MainWindow::GetFileNameFromMemory(uint32_t addr)
return strBuf; return strBuf;
} }
/*
void MainWindow::EventFinished(uint32_t replyEvent)
{
if (m_dbg.run_result == VM_WAIT_EVENT)
{
// Result event is in R0
m_chip32_ctx.registers[R0] = replyEvent;
m_dbg.run_result = VM_OK;
if (m_dbg.free_run)
{
m_runTimer->start(100);
}
else
{
stepInstruction();
}
}
}*/
void MainWindow::Play() void MainWindow::Play()
{ {
if (m_dbg.run_result == VM_FINISHED) if (m_dbg.run_result == VM_FINISHED)
@ -104,12 +85,14 @@ void MainWindow::Pause()
void MainWindow::Next() void MainWindow::Next()
{ {
Log("End of audio track");
m_eventQueue.push({VmEventType::EvNextButton});
} }
void MainWindow::Previous() void MainWindow::Previous()
{ {
Log("End of audio track");
m_eventQueue.push({VmEventType::EvPreviousButton});
} }
void MainWindow::EndOfAudio() void MainWindow::EndOfAudio()
@ -147,12 +130,12 @@ void MainWindow::ProcessStory()
m_chip32_ctx.registers[R0] = 0x01; m_chip32_ctx.registers[R0] = 0x01;
m_dbg.run_result = VM_OK; m_dbg.run_result = VM_OK;
} }
else if (event.type == VmEventType::EvLeftButton) else if (event.type == VmEventType::EvPreviousButton)
{ {
m_chip32_ctx.registers[R0] = 0x02; m_chip32_ctx.registers[R0] = 0x02;
m_dbg.run_result = VM_OK; m_dbg.run_result = VM_OK;
} }
else if (event.type == VmEventType::EvRightButton) else if (event.type == VmEventType::EvNextButton)
{ {
m_chip32_ctx.registers[R0] = 0x04; m_chip32_ctx.registers[R0] = 0x04;
m_dbg.run_result = VM_OK; m_dbg.run_result = VM_OK;
@ -284,6 +267,20 @@ void MainWindow::DrawMainMenuBar()
showOpenProject = true; showOpenProject = true;
} }
if (ImGui::BeginMenu("Open Recent"))
{
for (auto &e : m_recentProjects)
{
if (ImGui::MenuItem(e.c_str()))
{
OpenProject(e);
}
}
ImGui::EndMenu();
}
ImGui::Separator();
if (ImGui::MenuItem("Save project")) if (ImGui::MenuItem("Save project"))
{ {
SaveProject(); SaveProject();
@ -294,7 +291,7 @@ void MainWindow::DrawMainMenuBar()
CloseProject(); CloseProject();
} }
if (ImGui::MenuItem("Paramètres")) if (ImGui::MenuItem("Project settings"))
{ {
showParameters = true; showParameters = true;
} }
@ -332,11 +329,6 @@ void MainWindow::DrawMainMenuBar()
if (showOpenProject) if (showOpenProject)
{ {
std::string home = pf::getUserHome() + "/"; std::string home = pf::getUserHome() + "/";
#ifdef DEBUG
home = "/mnt/work/git/open-stories/ba869e4b-03d6-4249-9202-85b4cec767a7/";
#endif
ImGuiFileDialog::Instance()->OpenDialog("OpenProjectDlgKey", "Choose File", ".json", home, 1, nullptr, ImGuiFileDialogFlags_Modal); ImGuiFileDialog::Instance()->OpenDialog("OpenProjectDlgKey", "Choose File", ".json", home, 1, nullptr, ImGuiFileDialogFlags_Modal);
} }
@ -374,7 +366,7 @@ void MainWindow::Initialize()
gui.Initialize(); gui.Initialize();
// gui.ApplyTheme(); // gui.ApplyTheme();
m_editor.Initialize(); m_editorWindow.Initialize();
m_emulatorWindow.Initialize(); m_emulatorWindow.Initialize();
m_nodeEditorWindow.Initialize(); m_nodeEditorWindow.Initialize();
m_PropertiesWindow.Initialize(); m_PropertiesWindow.Initialize();
@ -416,31 +408,18 @@ bool MainWindow::ShowQuitConfirm()
void MainWindow::OpenProjectDialog() void MainWindow::OpenProjectDialog()
{ {
ImGui::SetNextWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
if (ImGuiFileDialog::Instance()->Display("OpenProjectDlgKey")) if (ImGuiFileDialog::Instance()->Display("OpenProjectDlgKey"))
{ {
// ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
// action if OK // action if OK
if (ImGuiFileDialog::Instance()->IsOk()) if (ImGuiFileDialog::Instance()->IsOk())
{ {
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName(); std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath(); std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
OpenProject(filePathName);
m_story.Initialize(filePathName);
nlohmann::json model;
if (m_story.Load(filePathName, model, m_resources))
{
Log("Open project success");
m_nodeEditorWindow.Load(model);
EnableProject();
}
else
{
Log("Open project error");
}
// RefreshProjectInformation(); // FIXME // RefreshProjectInformation(); // FIXME
} }
@ -449,33 +428,6 @@ void MainWindow::OpenProjectDialog()
} }
} }
void MainWindow::EnableProject()
{
auto proj = m_story.GetProjectFilePath();
// Add to recent if not exists
if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) != m_recentProjects.end())
{
m_recentProjects.push_back(proj);
// Limit to 10 recent projects
if (m_recentProjects.size() > 10) {
m_recentProjects.pop_back();
}
}
/* // FIXME
m_ostHmiDock->Open();
m_resourcesDock->Open();
m_scriptEditorDock->Open();
m_vmDock->Open();
m_ramView->Open();
m_romView->Open();
m_logDock->Open();
m_toolbar->SetActionsActive(true);
m_view->setEnabled(true);
*/
}
void MainWindow::NewProjectPopup() void MainWindow::NewProjectPopup()
{ {
static std::string projdir; static std::string projdir;
@ -618,7 +570,6 @@ void MainWindow::NewProjectPopup()
}; };
if (ImGui::Button("OK", ImVec2(120, 0))) if (ImGui::Button("OK", ImVec2(120, 0)))
{ {
bool valid{true}; bool valid{true};
@ -648,7 +599,7 @@ void MainWindow::NewProjectPopup()
m_story.SetUuid(UUID().String()); m_story.SetUuid(UUID().String());
SaveProject(); SaveProject();
EnableProject(); OpenProject(p.generic_string());
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -674,23 +625,61 @@ void MainWindow::SaveProject()
m_story.Save(model, m_resources); m_story.Save(model, m_resources);
} }
void MainWindow::OpenProject(const std::string &filename)
{
m_story.Initialize(filename);
nlohmann::json model;
if (m_story.Load(filename, model, m_resources))
{
Log("Open project success");
m_nodeEditorWindow.Load(model);
auto proj = m_story.GetProjectFilePath();
// Add to recent if not exists
if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) == m_recentProjects.end())
{
m_recentProjects.push_back(proj);
// Limit to 10 recent projects
if (m_recentProjects.size() > 10) {
m_recentProjects.pop_back();
}
// Save recent projects on disk
SaveParams();
}
m_nodeEditorWindow.Enable();
m_emulatorWindow.Enable();
m_consoleWindow.Enable();
m_editorWindow.Enable();
m_resourcesWindow.Enable();
m_PropertiesWindow.Enable();
}
else
{
Log("Open project error");
}
}
void MainWindow::CloseProject() void MainWindow::CloseProject()
{ {
m_story.Clear(); m_story.Clear();
m_resources.Clear();
m_nodeEditorWindow.Clear(); m_nodeEditorWindow.Clear();
m_emulatorWindow.ClearImage();
m_consoleWindow.ClearLog();
m_editorWindow.ClearErrors();
m_editorWindow.SetScript("");
// m_model.Clear(); m_nodeEditorWindow.Disable();
m_emulatorWindow.Disable();
// m_ostHmiDock->Close(); m_consoleWindow.Disable();
// m_resourcesDock->Close(); m_editorWindow.Disable();
// m_scriptEditorDock->Close(); m_resourcesWindow.Disable();
// m_vmDock->Close(); m_PropertiesWindow.Disable();
// m_ramView->Close();
// m_romView->Close();
// m_logDock->Close();
// m_toolbar->SetActionsActive(false);
// m_view->setEnabled(false);
} }
@ -717,7 +706,7 @@ void MainWindow::Loop()
// ------------ Draw all windows // ------------ Draw all windows
m_consoleWindow.Draw(); m_consoleWindow.Draw();
m_emulatorWindow.Draw(); m_emulatorWindow.Draw();
m_editor.Draw(); m_editorWindow.Draw();
m_resourcesWindow.Draw(); m_resourcesWindow.Draw();
m_nodeEditorWindow.Draw(); m_nodeEditorWindow.Draw();
@ -832,7 +821,7 @@ bool MainWindow::CompileToAssembler()
m_currentCode += buffer; m_currentCode += buffer;
} }
m_editor.SetScript(m_currentCode); m_editorWindow.SetScript(m_currentCode);
return true; return true;
} }
@ -866,14 +855,14 @@ void MainWindow::GenerateBinary()
{ {
Chip32::Assembler::Error err = m_assembler.GetLastError(); Chip32::Assembler::Error err = m_assembler.GetLastError();
Log(err.ToString(), true); Log(err.ToString(), true);
m_editor.AddError(err.line, err.message); // show also the error in the code editor m_editorWindow.AddError(err.line, err.message); // show also the error in the code editor
} }
} }
else else
{ {
Chip32::Assembler::Error err = m_assembler.GetLastError(); Chip32::Assembler::Error err = m_assembler.GetLastError();
Log(err.ToString(), true); Log(err.ToString(), true);
m_editor.AddError(err.line, err.message); // show also the error in the code editor m_editorWindow.AddError(err.line, err.message); // show also the error in the code editor
} }
} }
@ -899,7 +888,7 @@ void MainWindow::UpdateVmView()
if (ptr != m_assembler.End()) if (ptr != m_assembler.End())
{ {
m_dbg.line = (ptr->line - 1); m_dbg.line = (ptr->line - 1);
m_editor.HighlightLine(m_dbg.line); m_editorWindow.HighlightLine(m_dbg.line);
} }
else else
{ {
@ -949,10 +938,38 @@ void MainWindow::ConvertResources()
void MainWindow::SaveParams() void MainWindow::SaveParams()
{ {
nlohmann::json j;
nlohmann::json recents(m_recentProjects);
j["recents"] = recents;
std::string loc = pf::getConfigHome() + "/ost_settings.json";
std::ofstream o(loc);
o << std::setw(4) << j << std::endl;
Log("Saved settings to: " + loc);
} }
void MainWindow::LoadParams() void MainWindow::LoadParams()
{ {
try {
std::string loc = pf::getConfigHome() + "/ost_settings.json";
// read a JSON file
std::ifstream i(loc);
nlohmann::json j;
i >> j;
nlohmann::json recents = j["recents"];
for (auto& element : recents) {
if (std::filesystem::exists(element))
{
m_recentProjects.push_back(element);
}
}
}
catch(std::exception &e)
{
}
} }

View file

@ -88,7 +88,7 @@ public:
void Loop(); void Loop();
private: private:
enum VmEventType { EvNoEvent, EvStep, EvOkButton, EvLeftButton, EvRightButton, EvAudioFinished}; enum VmEventType { EvNoEvent, EvStep, EvOkButton, EvPreviousButton, EvNextButton, EvAudioFinished};
StoryProject m_story; StoryProject m_story;
@ -112,7 +112,7 @@ private:
Gui gui; Gui gui;
EmulatorWindow m_emulatorWindow; EmulatorWindow m_emulatorWindow;
ConsoleWindow m_consoleWindow; ConsoleWindow m_consoleWindow;
CodeEditor m_editor; CodeEditor m_editorWindow;
ResourcesWindow m_resourcesWindow; ResourcesWindow m_resourcesWindow;
@ -160,7 +160,7 @@ private:
void NewProjectPopup(); void NewProjectPopup();
void SaveProject(); void SaveProject();
void EnableProject(); void OpenProject(const std::string &filename);
void CloseProject(); void CloseProject();
void OpenProjectDialog(); void OpenProjectDialog();
void DrawStatusBar(); void DrawStatusBar();

View file

@ -2,7 +2,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <string.h> #include <string.h>
@ -73,14 +72,14 @@ void fwrite_u32_le(unsigned int v, FILE *fh) {
buf[1] = 0xff & (v >> 8); buf[1] = 0xff & (v >> 8);
buf[2] = 0xff & (v >> 16); buf[2] = 0xff & (v >> 16);
buf[3] = 0xff & (v >> 24); buf[3] = 0xff & (v >> 24);
int wrote = fwrite(buf, sizeof(unsigned int), 1, fh); (void) fwrite(buf, sizeof(unsigned int), 1, fh);
} }
void fwrite_u16_le(unsigned short v, FILE *fh) { void fwrite_u16_le(unsigned short v, FILE *fh) {
unsigned char buf[sizeof(unsigned short)]; unsigned char buf[sizeof(unsigned short)];
buf[0] = 0xff & (v ); buf[0] = 0xff & (v );
buf[1] = 0xff & (v >> 8); buf[1] = 0xff & (v >> 8);
int wrote = fwrite(buf, sizeof(unsigned short), 1, fh); (void) fwrite(buf, sizeof(unsigned short), 1, fh);
} }
int MediaConverter::WavWrite(const std::string &path, short *sample_data, MediaInfo &desc) int MediaConverter::WavWrite(const std::string &path, short *sample_data, MediaInfo &desc)

View file

@ -152,20 +152,27 @@ void NodeEditorWindow::Load(const nlohmann::json &model)
for (auto& connection : connectionJsonArray) for (auto& connection : connectionJsonArray)
{ {
Connection model = connection.get<Connection>();
CreateLink(model,
GetInputPin(model.inNodeId, model.inPortIndex),
GetOutputPin(model.outNodeId, model.outPortIndex));
}
}
void NodeEditorWindow::CreateLink(const Connection &model, ed::PinId inId, ed::PinId outId)
{
auto conn = std::make_shared<LinkInfo>(); auto conn = std::make_shared<LinkInfo>();
// our model *conn->model = model;
*conn->model = connection.get<Connection>();
// ImGui stuff for links // ImGui stuff for links
conn->ed_link->Id = BaseNode::GetNextId(); conn->ed_link->Id = BaseNode::GetNextId();
conn->ed_link->InputId = GetInputPin(conn->model->inNodeId, conn->model->inPortIndex); conn->ed_link->InputId = inId;
conn->ed_link->OutputId = GetOutputPin(conn->model->outNodeId, conn->model->outPortIndex); conn->ed_link->OutputId = outId;
// Since we accepted new link, lets add one to our list of links. // Since we accepted new link, lets add one to our list of links.
m_links.push_back(conn); m_links.push_back(conn);
}
} }
void NodeEditorWindow::Save(nlohmann::json &model) void NodeEditorWindow::Save(nlohmann::json &model)
@ -204,21 +211,12 @@ void NodeEditorWindow::Save(nlohmann::json &model)
nlohmann::json c; nlohmann::json c;
int index; Connection cnx = LinkToModel(linkInfo->ed_link->InputId, linkInfo->ed_link->OutputId);
for (const auto & n : m_nodes)
{
if (n->HasOnputPinId(linkInfo->ed_link->OutputId, index))
{
c["outNodeId"] = n->GetId();
c["outPortIndex"] = index;
}
if (n->HasInputPinId(linkInfo->ed_link->InputId, index)) c["outNodeId"] = cnx.outNodeId;
{ c["outPortIndex"] = cnx.outPortIndex;
c["inNodeId"] = n->GetId(); c["inNodeId"] = cnx.inNodeId;
c["inPortIndex"] = index; c["inPortIndex"] = cnx.inPortIndex;
}
}
connections.push_back(c); connections.push_back(c);
} }
@ -227,6 +225,28 @@ void NodeEditorWindow::Save(nlohmann::json &model)
ed::SetCurrentEditor(nullptr); ed::SetCurrentEditor(nullptr);
} }
Connection NodeEditorWindow::LinkToModel(ed::PinId InputId, ed::PinId OutputId)
{
Connection c;
int index;
for (const auto & n : m_nodes)
{
if (n->HasOnputPinId(OutputId, index))
{
c.outNodeId = n->GetId();
c.outPortIndex = index;
}
if (n->HasInputPinId(InputId, index))
{
c.inNodeId = n->GetId();
c.inPortIndex = index;
}
}
return c;
}
uint32_t NodeEditorWindow::FindFirstNode() const uint32_t NodeEditorWindow::FindFirstNode() const
{ {
uint32_t id = 0; uint32_t id = 0;
@ -389,11 +409,12 @@ void NodeEditorWindow::Draw()
// ed::AcceptNewItem() return true when user release mouse button. // ed::AcceptNewItem() return true when user release mouse button.
if (ed::AcceptNewItem()) if (ed::AcceptNewItem())
{ {
// Since we accepted new link, lets add one to our list of links. Connection model = LinkToModel(inputPinId, outputPinId);
// m_Links.push_back({ ed::LinkId(BaseNode::GetNextId()), inputPinId, outputPinId });
CreateLink(model, inputPinId, outputPinId);
// Draw new link. // Draw new link.
// ed::Link(m_Links.back().Id, m_Links.back().InputId, m_Links.back().OutputId); ed::Link(m_links.back()->ed_link->Id, inputPinId, outputPinId);
} }
// You may choose to reject connection between these nodes // You may choose to reject connection between these nodes

View file

@ -117,5 +117,7 @@ private:
ed::PinId GetOutputPin(unsigned long modelNodeId, int pinIndex); ed::PinId GetOutputPin(unsigned long modelNodeId, int pinIndex);
uint32_t FindFirstNode() const; uint32_t FindFirstNode() const;
int GenerateNodeId(); int GenerateNodeId();
void CreateLink(const Connection &model, ed::PinId inId, ed::PinId outId);
Connection LinkToModel(ed::PinId InputId, ed::PinId OutputId);
}; };

View file

@ -25,9 +25,6 @@ void PropertiesWindow::Draw()
WindowBase::BeginDraw(); WindowBase::BeginDraw();
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver); ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
ImGui::SeparatorText("Project");
ImGui::SeparatorText("Selected node"); ImGui::SeparatorText("Selected node");

View file

@ -20,12 +20,11 @@ bool WindowBase::BeginDraw()
void WindowBase::EndDraw() void WindowBase::EndDraw()
{ {
ImGui::End();
if (m_disabled) if (m_disabled)
{ {
ImGui::EndDisabled(); ImGui::EndDisabled();
} }
ImGui::End();
} }

View file

@ -17,6 +17,14 @@ public:
bool BeginDraw(); bool BeginDraw();
void EndDraw(); void EndDraw();
void Disable() {
m_disabled = true;
}
void Enable() {
m_disabled = false;
}
private: private:
bool m_disabled{false}; bool m_disabled{false};