diff --git a/graphicswin.cpp b/graphicswin.cpp index c956495..03c2976 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -14,6 +14,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { { 0, "&File", 0, NULL }, { 1, "&New\tCtrl+N", MNU_NEW, 'N'|C, mFile }, { 1, "&Open...\tCtrl+O", MNU_OPEN, 'O'|C, mFile }, +{10, "&Open Recent", MNU_OPEN_RECENT, 0, mFile }, { 1, "&Save\tCtrl+S", MNU_SAVE, 'S'|C, mFile }, { 1, "Save &As...", MNU_SAVE_AS, 0, mFile }, { 1, NULL, 0, 0, NULL }, @@ -37,17 +38,17 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { { 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, mView }, { 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, mView }, -{ 0, "&Group", 0, 0, NULL }, -{ 1, "New &Drawing in 3d\tShift+Ctrl+D", MNU_GROUP_3D, 'D'|S|C, mGrp }, -{ 1, "New Drawing in Workplane\tShift+Ctrl+W",MNU_GROUP_WRKPL, 'W'|S|C, mGrp }, +{ 0, "&New Feature", 0, 0, NULL }, +{ 1, "&Drawing in 3d\tShift+Ctrl+D", MNU_GROUP_3D, 'D'|S|C, mGrp }, +{ 1, "Drawing in Workplane\tShift+Ctrl+W", MNU_GROUP_WRKPL, 'W'|S|C, mGrp }, { 1, NULL, 0, NULL }, -{ 1, "New Step &Translating\tShift+Ctrl+R", MNU_GROUP_TRANS, 'T'|S|C,mGrp }, -{ 1, "New Step &Rotating\tShift+Ctrl+T", MNU_GROUP_ROT, 'R'|S|C,mGrp }, +{ 1, "Step &Translating\tShift+Ctrl+R", MNU_GROUP_TRANS, 'T'|S|C,mGrp }, +{ 1, "Step &Rotating\tShift+Ctrl+T", MNU_GROUP_ROT, 'R'|S|C,mGrp }, { 1, NULL, 0, 0, NULL }, -{ 1, "New Extrusion\tShift+Ctrl+X", MNU_GROUP_EXTRUDE, 'X'|S|C,mGrp }, +{ 1, "Extrusion\tShift+Ctrl+X", MNU_GROUP_EXTRUDE, 'X'|S|C,mGrp }, { 1, NULL, 0, 0, NULL }, -{ 1, "New Boolean Difference", 0, 0, NULL }, -{ 1, "New Boolean Union", 0, 0, NULL }, +{ 1, "Import...\tShift+Ctrl+I", MNU_GROUP_IMPORT, 'I'|S|C,mGrp }, +{11, "Import Recent", MNU_GROUP_RECENT, 0, mGrp }, { 0, "&Request", 0, NULL }, { 1, "Draw in &Workplane\tW", MNU_SEL_WORKPLANE, 'W', mReq }, diff --git a/solvespace.cpp b/solvespace.cpp index 94623d5..bc775a9 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -6,9 +6,17 @@ void SolveSpace::Init(char *cmdLine) { if(strlen(cmdLine) == 0) { NewFile(); } else { - LoadFromFile(cmdLine); + if(LoadFromFile(cmdLine)) { + strcpy(saveFile, cmdLine); + } else { + NewFile(); + } } + AfterNewFile(); +} + +void SolveSpace::AfterNewFile(void) { GenerateAll(false, 0, INT_MAX); TW.Init(); @@ -302,25 +310,85 @@ void SolveSpace::SolveGroup(hGroup hg) { FreeAllTemporary(); } +void SolveSpace::RemoveFromRecentList(char *file) { + int src, dest; + dest = 0; + for(src = 0; src < MAX_RECENT; src++) { + if(strcmp(file, RecentFile[src]) != 0) { + if(src != dest) strcpy(RecentFile[dest], RecentFile[src]); + dest++; + } + } + while(dest < MAX_RECENT) strcpy(RecentFile[dest++], ""); + RefreshRecentMenus(); +} +void SolveSpace::AddToRecentList(char *file) { + RemoveFromRecentList(file); + + int src; + for(src = MAX_RECENT - 2; src >= 0; src--) { + strcpy(RecentFile[src+1], RecentFile[src]); + } + strcpy(RecentFile[0], file); + RefreshRecentMenus(); +} + void SolveSpace::MenuFile(int id) { + char *slvsPattern = + "SolveSpace Models (*.slvs)\0*.slvs\0All Files (*)\0*\0\0"; + char *slvsExt = "slvs"; + + if(id >= RECENT_OPEN && id < (RECENT_OPEN+MAX_RECENT)) { + char newFile[MAX_PATH]; + strcpy(newFile, RecentFile[id-RECENT_OPEN]); + RemoveFromRecentList(newFile); + if(SS.LoadFromFile(newFile)) { + strcpy(SS.saveFile, newFile); + AddToRecentList(newFile); + } else { + strcpy(SS.saveFile, ""); + SS.NewFile(); + } + SS.AfterNewFile(); + return; + } + switch(id) { case GraphicsWindow::MNU_NEW: + strcpy(SS.saveFile, ""); SS.NewFile(); - SS.GenerateAll(false); - SS.TW.Init(); - SS.GW.Init(); - SS.TW.Show(); + SS.AfterNewFile(); break; - case GraphicsWindow::MNU_OPEN: + case GraphicsWindow::MNU_OPEN: { + char newFile[MAX_PATH] = ""; + if(GetOpenFile(newFile, slvsExt, slvsPattern)) { + if(SS.LoadFromFile(newFile)) { + strcpy(SS.saveFile, newFile); + AddToRecentList(newFile); + } else { + strcpy(SS.saveFile, ""); + SS.NewFile(); + } + SS.AfterNewFile(); + } break; + } case GraphicsWindow::MNU_SAVE: - SS.SaveToFile("t.slvs"); - break; + case GraphicsWindow::MNU_SAVE_AS: { + char newFile[MAX_PATH]; + strcpy(newFile, SS.saveFile); + if(id == GraphicsWindow::MNU_SAVE_AS || strlen(newFile)==0) { + if(!GetSaveFile(newFile, slvsExt, slvsPattern)) break; + } - case GraphicsWindow::MNU_SAVE_AS: + if(SS.SaveToFile(newFile)) { + AddToRecentList(newFile); + strcpy(SS.saveFile, newFile); + } break; + } case GraphicsWindow::MNU_EXIT: break; diff --git a/solvespace.h b/solvespace.h index 8ba10fe..5d5bcfb 100644 --- a/solvespace.h +++ b/solvespace.h @@ -42,6 +42,12 @@ class ExprVector; class ExprQuaternion; // From the platform-specific code. +#define MAX_RECENT 8 +#define RECENT_OPEN (0xf000) +#define RECENT_IMPORT (0xf100) +extern char RecentFile[MAX_RECENT][MAX_PATH]; +void RefreshRecentMenus(void); + int SaveFileYesNoCancel(void); BOOL GetSaveFile(char *file, char *defExtension, char *selPattern); BOOL GetOpenFile(char *file, char *defExtension, char *selPattern); @@ -202,6 +208,9 @@ public: FILE *fh; void Init(char *cmdLine); + void AfterNewFile(void); + static void RemoveFromRecentList(char *file); + static void AddToRecentList(char *file); char saveFile[MAX_PATH]; bool unsaved; diff --git a/ui.h b/ui.h index 4f6c445..0a39a0b 100644 --- a/ui.h +++ b/ui.h @@ -110,6 +110,7 @@ public: // File MNU_NEW = 100, MNU_OPEN, + MNU_OPEN_RECENT, MNU_SAVE, MNU_SAVE_AS, MNU_EXIT, @@ -140,6 +141,8 @@ public: MNU_GROUP_EXTRUDE, MNU_GROUP_ROT, MNU_GROUP_TRANS, + MNU_GROUP_IMPORT, + MNU_GROUP_RECENT, // Constrain MNU_DISTANCE_DIA, MNU_ANGLE, diff --git a/win32/w32main.cpp b/win32/w32main.cpp index 0db4f43..52e38fe 100644 --- a/win32/w32main.cpp +++ b/win32/w32main.cpp @@ -33,11 +33,14 @@ int TextWndHalfRows; // The height of our window, in half-row units HWND GraphicsWnd; HGLRC GraphicsHpgl; HWND GraphicsEditControl; -HMENU SubMenus[100]; struct { int x, y; } LastMousePos; +char RecentFile[MAX_RECENT][MAX_PATH]; +HMENU SubMenus[100]; +HMENU RecentOpenMenu, RecentImportMenu; + int ClientIsSmallerBy; HFONT FixedFont, LinkFont; @@ -604,12 +607,22 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_COMMAND: { if(HIWORD(wParam) == 0) { int id = LOWORD(wParam); - for(int i = 0; SS.GW.menu[i].level >= 0; i++) { + if((id >= RECENT_OPEN && id < (RECENT_OPEN + MAX_RECENT))) { + SolveSpace::MenuFile(id); + break; + } + if((id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT))) { + Group::MenuGroup(id); + break; + } + int i; + for(i = 0; SS.GW.menu[i].level >= 0; i++) { if(id == SS.GW.menu[i].id) { (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id); break; } } + if(SS.GW.menu[i].level < 0) oops(); } break; } @@ -710,6 +723,25 @@ void EnableMenuById(int id, BOOL enabled) { MenuById(id, enabled, FALSE); } +static void DoRecent(HMENU m, int base) +{ + while(DeleteMenu(m, 0, MF_BYPOSITION)) + ; + int i, c = 0; + for(i = 0; i < MAX_RECENT; i++) { + char *s = RecentFile[i]; + if(*s) { + AppendMenu(m, MF_STRING, base+i, s); + c++; + } + } + if(c == 0) AppendMenu(m, MF_STRING | MF_GRAYED, 0, "(no recent files)"); +} +void RefreshRecentMenus(void) +{ + DoRecent(RecentOpenMenu, RECENT_OPEN); + DoRecent(RecentImportMenu, RECENT_IMPORT); +} HMENU CreateGraphicsWindowMenus(void) { @@ -728,14 +760,23 @@ HMENU CreateGraphicsWindowMenus(void) if(subMenu >= arraylen(SubMenus)) oops(); SubMenus[subMenu] = m; subMenu++; - } else { + } else if(SS.GW.menu[i].level == 1) { if(SS.GW.menu[i].label) { AppendMenu(m, MF_STRING, SS.GW.menu[i].id, SS.GW.menu[i].label); } else { AppendMenu(m, MF_SEPARATOR, SS.GW.menu[i].id, ""); } - } + } else if(SS.GW.menu[i].level == 10) { + RecentOpenMenu = CreateMenu(); + AppendMenu(m, MF_STRING | MF_POPUP, + (UINT_PTR)RecentOpenMenu, SS.GW.menu[i].label); + } else if(SS.GW.menu[i].level == 11) { + RecentImportMenu = CreateMenu(); + AppendMenu(m, MF_STRING | MF_POPUP, + (UINT_PTR)RecentImportMenu, SS.GW.menu[i].label); + } else oops(); } + RefreshRecentMenus(); return top; } @@ -819,6 +860,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, InitCommonControls(); + int i; + for(i = 0; i < MAX_RECENT; i++) { + char name[100]; + sprintf(name, "RecentFile_%d", i); + ThawStringF(RecentFile[i], MAX_PATH, FREEZE_SUBKEY, name); + } + // A monospaced font FixedFont = CreateFont(TEXT_HEIGHT-4, TEXT_WIDTH, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, @@ -860,8 +908,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, TranslateMessage(&msg); DispatchMessage(&msg); } + + // Write everything back to the registry FreezeWindowPos(TextWnd); FreezeWindowPos(GraphicsWnd); + for(i = 0; i < MAX_RECENT; i++) { + char name[100]; + sprintf(name, "RecentFile_%d", i); + FreezeStringF(RecentFile[i], FREEZE_SUBKEY, name); + } return 0; }