Skip to content

Commit 98dfcfb

Browse files
committed
Recent projects
1 parent f1dc808 commit 98dfcfb

4 files changed

Lines changed: 101 additions & 25 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,4 @@ FodyWeavers.xsd
390390

391391
desktop.ini
392392
out/
393+
3DRadSpace/Data/RecentProjects.txt

3DRadSpace/3DRadSpace_Editor_WindowsDX11/Frontend/Windows/EditorWindow.cpp

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,42 @@ void EditorWindow::_openProject(const std::filesystem::path& filename)
5353
gizmo->Load();
5454
}
5555

56-
TVITEMA item{};
57-
item.mask = TVIF_TEXT | TVIF_PARAM;
58-
item.pszText = const_cast<char*>(object->Name.c_str());
59-
item.cChildren = 0;
60-
item.lParam = i;
56+
++i;
57+
}
6158

62-
TVINSERTSTRUCTA insertStruct{};
63-
insertStruct.item = item;
59+
for (int i = 0; auto& instance : *(editor->Objects))
60+
{
61+
auto object = instance.Object.get();
62+
63+
if (!object->HasParent())
64+
{
65+
TVITEMA item{};
66+
item.mask = TVIF_TEXT | TVIF_PARAM;
67+
item.pszText = const_cast<char*>(object->Name.c_str());
68+
item.cChildren = 1;
69+
item.lParam = i;
6470

65-
SendMessageA(_treeView, TVM_INSERTITEMA, 0, reinterpret_cast<LPARAM>(&insertStruct));
71+
TVINSERTSTRUCTA insertStruct{};
72+
insertStruct.item = item;
6673

67-
++i;
74+
SendMessageA(_treeView, TVM_INSERTITEMA, 0, reinterpret_cast<LPARAM>(&insertStruct));
75+
}
76+
else
77+
{
78+
TVITEMA item{};
79+
item.mask = TVIF_TEXT | TVIF_PARAM;
80+
item.pszText = const_cast<char*>(object->Name.c_str());
81+
item.cChildren = 1;
82+
item.lParam = i;
83+
84+
TVINSERTSTRUCTA insertStruct{};
85+
//TODO: identify parent object then insert into an parent item
86+
87+
SendMessageA(_treeView, TVM_INSERTITEMA, 0, reinterpret_cast<LPARAM>(&insertStruct));
88+
}
6889
}
90+
91+
_addRecentProject(filename);
6992
}
7093

7194
void EditorWindow::_saveProject(const std::filesystem::path &filename)
@@ -101,6 +124,7 @@ void EditorWindow::_writeProject(const std::filesystem::path& fileName)
101124
_changesSaved = true;
102125
_currentFile = fileName;
103126
Serializer::SaveProject(editor->Objects.get(), editor->Content.get(), fileName);
127+
_addRecentProject(fileName);
104128
}
105129

106130
void EditorWindow::_findUpdate()
@@ -319,7 +343,7 @@ EditorWindow::EditorWindow(HINSTANCE hInstance,const std::string &cmdArgs) :
319343
wndclass.hInstance = hInstance;
320344
wndclass.lpfnWndProc = EditorWindow_WndProc;
321345
wndclass.lpszClassName = EditorWindowClassName;
322-
wndclass.hIcon = LoadIconA(hInstance,MAKEINTRESOURCEA(IDI_ICON1));
346+
wndclass.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON1));
323347
wndclass.hCursor = LoadCursorA(nullptr, MAKEINTRESOURCEA(32512)); //IDI_ARROW
324348

325349
ATOM a = RegisterClassA(&wndclass);
@@ -333,23 +357,27 @@ EditorWindow::EditorWindow(HINSTANCE hInstance,const std::string &cmdArgs) :
333357
if(recentProjectsMenu == nullptr) throw Exception("Failed to create File > Recent files menu!");
334358

335359
std::ifstream recent_projects(RecentProjectFile);
336-
//Create the file if it doesn't exist or if it is empty
337-
if (recent_projects.bad() || recent_projects.fail())
338-
{
339-
std::ofstream create_recent_projects(RecentProjectFile);
340-
create_recent_projects.close();
341360

342-
AppendMenuA(recentProjectsMenu, MF_STRING, 0, "...");
361+
int recentCount = 0;
362+
if (recent_projects.is_open()) {
363+
//Loop each line
364+
for(int i = 0; recent_projects && i < 10; i++)
365+
{
366+
std::string filename;
367+
std::getline(recent_projects, filename);
368+
if (!filename.empty())
369+
{
370+
_recentFiles.push_back(filename);
371+
AppendMenuA(recentProjectsMenu, MF_STRING, CMD_OpenRecentFile1 + static_cast<UINT_PTR>(i), filename.c_str());
372+
recentCount++;
373+
}
374+
}
375+
recent_projects.close();
343376
}
344-
//Loop each line
345-
for(int i = 0; recent_projects; i++)
346-
{
347-
std::string filename;
348-
std::getline(recent_projects, filename);
349-
if(!filename.empty())
350-
AppendMenuA(recentProjectsMenu, MF_STRING, CMD_OpenRecentFile1 + static_cast<UINT_PTR>(i), filename.c_str());
377+
378+
if (recentCount == 0) {
379+
AppendMenuA(recentProjectsMenu, MF_STRING | MF_GRAYED, 0, "No recent projects");
351380
}
352-
recent_projects.close();
353381

354382
//Create the rest of the menu.
355383
HMENU fileMenu = CreateMenu();
@@ -489,7 +517,7 @@ EditorWindow::EditorWindow(HINSTANCE hInstance,const std::string &cmdArgs) :
489517
"",
490518
WS_CHILD | WS_VISIBLE | WS_BORDER,
491519
0,
492-
0,
520+
0,
493521
150,
494522
600,
495523
_mainWindow,
@@ -650,6 +678,38 @@ void EditorWindow::SelectObject(std::optional<unsigned> id)
650678

651679
void SetWorkingDirectory();
652680

681+
void EditorWindow::OpenRecentProject(uint8_t id)
682+
{
683+
if (id >= _recentFiles.size()) return;
684+
685+
SetWorkingDirectory();
686+
gEditorWindow->_openProject(gEditorWindow->_recentFiles[id]);
687+
}
688+
689+
void EditorWindow::_addRecentProject(const std::filesystem::path& filename)
690+
{
691+
// Remove if already present
692+
auto it = std::find(_recentFiles.begin(), _recentFiles.end(), filename);
693+
if (it != _recentFiles.end())
694+
_recentFiles.erase(it);
695+
696+
// Add to end
697+
_recentFiles.push_back(filename);
698+
699+
// Keep only 10 recent files
700+
if (_recentFiles.size() > 10)
701+
_recentFiles.erase(_recentFiles.begin());
702+
703+
// Only write if there are recent files
704+
if (!_recentFiles.empty()) {
705+
SetWorkingDirectory();
706+
std::ofstream recent_projects(RecentProjectFile, std::ios::trunc);
707+
for (const auto& file : _recentFiles)
708+
recent_projects << file.string() << std::endl;
709+
recent_projects.close();
710+
}
711+
}
712+
653713
LRESULT __stdcall EditorWindow_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
654714
{
655715
switch(msg)
@@ -719,24 +779,34 @@ LRESULT __stdcall EditorWindow_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
719779
}
720780

721781
case CMD_OpenRecentFile1:
782+
gEditorWindow->OpenRecentProject(0);
722783
break;
723784
case CMD_OpenRecentFile1 + 1:
785+
gEditorWindow->OpenRecentProject(1);
724786
break;
725787
case CMD_OpenRecentFile1 + 2:
788+
gEditorWindow->OpenRecentProject(2);
726789
break;
727790
case CMD_OpenRecentFile1 + 3:
791+
gEditorWindow->OpenRecentProject(3);
728792
break;
729793
case CMD_OpenRecentFile1 + 4:
794+
gEditorWindow->OpenRecentProject(4);
730795
break;
731796
case CMD_OpenRecentFile1 + 5:
797+
gEditorWindow->OpenRecentProject(5);
732798
break;
733799
case CMD_OpenRecentFile1 + 6:
800+
gEditorWindow->OpenRecentProject(6);
734801
break;
735802
case CMD_OpenRecentFile1 + 7:
803+
gEditorWindow->OpenRecentProject(7);
736804
break;
737805
case CMD_OpenRecentFile1 + 8:
806+
gEditorWindow->OpenRecentProject(8);
738807
break;
739808
case CMD_OpenRecentFile1 + 9:
809+
gEditorWindow->OpenRecentProject(9);
740810
break;
741811

742812
case CMD_SaveProject:
@@ -988,6 +1058,7 @@ LRESULT __stdcall EditorWindow_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA
9881058
HMENU objectMenu = CreatePopupMenu();
9891059
if(objectMenu == nullptr) throw std::exception("Failed to create a popup menu!");
9901060

1061+
AppendMenuA(objectMenu, MF_STRING, CMD_AddChildObject, "Add child object");
9911062
AppendMenuA(objectMenu, MF_STRING, CMD_EditObject, "Edit object");
9921063
AppendMenuA(objectMenu, MF_STRING, CMD_DeselectObject, "Deselect object");
9931064
AppendMenuA(objectMenu, MF_STRING, CMD_DeleteObject, "Delete object");

3DRadSpace/3DRadSpace_Editor_WindowsDX11/Frontend/Windows/EditorWindow.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,17 @@ class EditorWindow
6666
void _openProject(const std::filesystem::path& filename);
6767
void _saveProject(const std::filesystem::path& filename = "");
6868
void _writeProject(const std::filesystem::path& filename);
69+
6970
void _findUpdate();
71+
void _addRecentProject(const std::filesystem::path& filename);
7072

7173
HTREEITEM _getSelectedListViewItem();
7274
std::pair<HTREEITEM, std::optional<unsigned>> _getSelectedObjectID();
7375

7476
void _parseCmdArgs(const std::string & cmdArgs);
7577

7678
std::chrono::time_point<std::chrono::high_resolution_clock> _lastFrameTime{};
79+
std::vector<std::filesystem::path> _recentFiles;
7780
public:
7881
EditorWindow(HINSTANCE hInstance, const std::string &cmdArgs);
7982

@@ -89,6 +92,7 @@ class EditorWindow
8992

9093
IObject* CreateNewObject();
9194
void SelectObject(std::optional<unsigned> id);
95+
void OpenRecentProject(uint8_t id);
9296

9397
friend LRESULT __stdcall EditorWindow_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
9498
friend class Engine3DRadSpace::Game;

3DRadSpace/Data/RecentProjects.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)