diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj
index cec773bd8..9c1d31dde 100644
--- a/openBeken_win32_mvsc2017.vcxproj
+++ b/openBeken_win32_mvsc2017.vcxproj
@@ -522,6 +522,7 @@
+
@@ -566,6 +567,7 @@
+
diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters
index 5587103ce..6086f6857 100644
--- a/openBeken_win32_mvsc2017.vcxproj.filters
+++ b/openBeken_win32_mvsc2017.vcxproj.filters
@@ -399,6 +399,9 @@
Simulator
+
+ Simulator
+
@@ -476,6 +479,9 @@
Simulator
+
+ Simulator
+
diff --git a/src/sim/RecentList.cpp b/src/sim/RecentList.cpp
new file mode 100644
index 000000000..1ce966177
--- /dev/null
+++ b/src/sim/RecentList.cpp
@@ -0,0 +1,51 @@
+#ifdef WINDOWS
+#include "RecentList.h"
+#include "../cJSON/cJSON.h"
+
+void CRecentList::remove(const char *s) {
+ for (int i = recents.size() - 1; i >= 0; i--) {
+ if (!stricmp(recents[i].c_str(), s)) {
+ recents.removeAt(i);
+ }
+ }
+
+}
+void CRecentList::registerAndSave(const char *s) {
+ remove(s);
+ recents.insert(recents.begin(), s);
+ save();
+}
+bool CRecentList::load(const char *fname) {
+ char *jsonData;
+ jsonData = FS_ReadTextFile(fname);
+ if (jsonData == 0) {
+ return 0;
+ }
+ cJSON *n_jSim = cJSON_Parse(jsonData);
+ cJSON *n_jObjects = cJSON_GetObjectItemCaseSensitive(n_jSim, "recents");
+ cJSON *jObject;
+ clear();
+ cJSON_ArrayForEach(jObject, n_jObjects)
+ {
+ cJSON *cPath = cJSON_GetObjectItemCaseSensitive(jObject, "path");
+ push_back(cPath->valuestring);
+ }
+ return true;
+}
+void CRecentList::save(const char *fname) {
+ cJSON *root_sim = cJSON_CreateObject();
+ cJSON *main_objects = cJSON_AddObjectToObject(root_sim, "recents");
+ for (int i = 0; i < size(); i++) {
+ const char *path = get(i);
+ cJSON *j_obj = cJSON_AddObjectToObject(main_objects, "recent");
+ cJSON_AddStringToObject(j_obj, "path", path);
+ }
+ char *msg = cJSON_Print(root_sim);
+
+ FS_WriteTextFile(msg, fname);
+
+ free(msg);
+}
+
+#endif
+
diff --git a/src/sim/RecentList.h b/src/sim/RecentList.h
new file mode 100644
index 000000000..1c23d923f
--- /dev/null
+++ b/src/sim/RecentList.h
@@ -0,0 +1,36 @@
+#ifndef __RECENTLIST_H__
+#define __RECENTLIST_H__
+
+#include "sim_local.h"
+
+#define RECENTS_FILE_PATH "recents.json"
+
+class CRecentList {
+ TArray recents;
+
+ void remove(const char *s);
+public:
+ int size() const {
+ return recents.size();
+ }
+ const char *get(int i) const {
+ return recents[i].c_str();
+ }
+ void push_back(const char *s) {
+ recents.push_back(s);
+ }
+ int getSizeCappedAt(int mx) const {
+ if (mx < recents.size())
+ return mx;
+ return recents.size();
+ }
+ void clear() {
+ recents.clear();
+ }
+ void registerAndSave(const char *s);
+ bool load(const char *path = RECENTS_FILE_PATH);
+ void save(const char *path = RECENTS_FILE_PATH);
+
+};
+
+#endif
diff --git a/src/sim/Simulator.cpp b/src/sim/Simulator.cpp
index 631608e79..f6fe2373a 100644
--- a/src/sim/Simulator.cpp
+++ b/src/sim/Simulator.cpp
@@ -20,6 +20,7 @@
#include "WinMenuBar.h"
#include "SaveLoad.h"
#include "sim_import.h"
+#include "RecentList.h"
CSimulator::CSimulator() {
@@ -37,6 +38,8 @@ CSimulator::CSimulator() {
solver = new CSolver();
saveLoad = new CSaveLoad();
saveLoad->setSimulator(this);
+ recents = new CRecentList();
+ recents->load();
}
void CSimulator::setTool(Tool_Base *tb) {
@@ -261,6 +264,7 @@ bool CSimulator::loadSimulation(const char *s) {
projectPath = s;
project = saveLoad->loadProjectFile(s);
sim = saveLoad->loadSimulationFromFile(simPath.c_str());
+ recents->registerAndSave(projectPath.c_str());
SIM_ClearOBK();
SIM_SetupFlashFileReading(memPath.c_str());
SIM_DoFreshOBKBoot();
@@ -292,6 +296,7 @@ bool CSimulator::saveSimulationAs(const char *s) {
printf("CSimulator::saveSimulationAs: memPath %s\n", memPath.c_str());
FS_CreateDirectoriesForPath(simPath.c_str());
FS_CreateDirectoriesForPath(memPath.c_str());
+ recents->registerAndSave(projectPath.c_str());
saveLoad->saveProjectToFile(project, projectPath.c_str());
saveLoad->saveSimulationToFile(sim, simPath.c_str());
SIM_SaveFlashData(memPath.c_str());
diff --git a/src/sim/Simulator.h b/src/sim/Simulator.h
index dd742d348..046d5fec0 100644
--- a/src/sim/Simulator.h
+++ b/src/sim/Simulator.h
@@ -22,6 +22,7 @@ class CSimulator {
class CProject *project;
bool bSchematicModified;
class CText *currentlyEditingText;
+ class CRecentList *recents;
void onKeyDown(int keyCode);
void setTool(class Tool_Base *tb);
@@ -37,6 +38,9 @@ public:
class CSimulation*getSim() {
return sim;
}
+ class CRecentList *getRecents() {
+ return recents;
+ }
class PrefabManager*getPfbs() {
return prefabs;
}
diff --git a/src/sim/WinMenuBar.cpp b/src/sim/WinMenuBar.cpp
index ad269e32a..894b1051d 100644
--- a/src/sim/WinMenuBar.cpp
+++ b/src/sim/WinMenuBar.cpp
@@ -2,6 +2,7 @@
#include "WinMenuBar.h"
#include "Simulator.h"
+#include "RecentList.h"
#include
#pragma comment (lib, "nfd_d.lib")
@@ -16,6 +17,8 @@ enum {
ID_SAVEAS,
ID_SAVE,
ID_EXIT,
+ ID_OPEN_RECENT_FIRST,
+ ID_OPEN_RECENT_LAST = ID_OPEN_RECENT_FIRST + 100,
ID_OPTIONS,
ID_ABOUT,
};
@@ -25,6 +28,7 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) {
hFile = CreateMenu();
hEdit = CreateMenu();
hHelp = CreateMenu();
+ HMENU hRecent = CreateMenu();
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFile, "File");
AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hEdit, "Edit");
@@ -35,6 +39,16 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) {
AppendMenu(hFile, MF_STRING, ID_LOAD, "Load...");
AppendMenu(hFile, MF_STRING, ID_SAVE, "Save");
AppendMenu(hFile, MF_STRING, ID_SAVEAS, "Save as...");
+ AppendMenu(hFile, MF_POPUP, (UINT_PTR)hRecent, "Open recent");
+ CRecentList *rList = sim->getRecents();
+ recents.clear();
+ for (int i = 0; i < rList->getSizeCappedAt(10); i++) {
+ const char *entr = rList->get(i);
+ recents.push_back(entr);
+ CString tmp = "Open ";
+ tmp.append(entr);
+ AppendMenu(hRecent, MF_STRING, ID_OPEN_RECENT_FIRST + i, tmp.c_str());
+ }
AppendMenu(hFile, MF_STRING, ID_EXIT, "Exit");
AppendMenu(hEdit, MF_STRING, ID_OPTIONS, "Options");
@@ -78,33 +92,40 @@ void CWinMenuBar::processEvent(const SDL_Event &Event) {
if (Event.type == SDL_SYSWMEVENT) {
if (Event.syswm.msg->msg.win.msg == WM_COMMAND)
{
- if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_EXIT)
+ int id = LOWORD(Event.syswm.msg->msg.win.wParam);
+ if (id == ID_EXIT)
{
sim->onUserClose();
}
- else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_NEW)
+ else if (id == ID_NEW)
{
sim->createSimulation(false);
}
- else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_NEW_DEMO)
+ else if (id == ID_NEW_DEMO)
{
sim->createSimulation(true);
}
- else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_LOAD)
+ else if (id == ID_LOAD)
{
result = NFD_OpenDialog("obkproj", NULL, &outPath);
if (result == NFD_OKAY) {
sim->loadSimulation(outPath);
}
}
- else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_SAVEAS)
+ else if (id == ID_SAVEAS)
{
showSaveAsDialog();
}
- else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_SAVE)
+ else if (id == ID_SAVE)
{
sim->saveOrShowSaveAsDialogIfNeeded();
}
+ else if (id >= ID_OPEN_RECENT_FIRST && id <= ID_OPEN_RECENT_LAST)
+ {
+ int recentID = id - ID_OPEN_RECENT_FIRST;
+ const char *recentStr = recents[recentID].c_str();
+ sim->loadSimulation(outPath);
+ }
}
}
}
diff --git a/src/sim/WinMenuBar.h b/src/sim/WinMenuBar.h
index dd14909f4..1d8aedf6d 100644
--- a/src/sim/WinMenuBar.h
+++ b/src/sim/WinMenuBar.h
@@ -11,6 +11,7 @@ class CWinMenuBar {
HMENU hFile;
HMENU hEdit;
HMENU hHelp;
+ TArray recents;
void createWindowsMenu(HWND windowRef);
HWND getHWNDForSDLWindow(SDL_Window* win);
diff --git a/src/sim/sim_local.h b/src/sim/sim_local.h
index 84c1634f6..74ffe2764 100644
--- a/src/sim/sim_local.h
+++ b/src/sim/sim_local.h
@@ -50,6 +50,9 @@ public:
void remove(T o) {
this->erase(std::remove(this->begin(), this->end(), o), this->end());
}
+ void removeAt(int i) {
+ this->erase(this->begin() + i);
+ }
bool contains(const T&o) const {
for (unsigned int i = 0; i < size(); i++) {
if ((*this)[i] == o)