2 public import static "ecere"
3 public import static "ec"
9 import "GlobalSettingsDialog"
10 import "NewProjectDialog"
11 import "FindInFilesDialog"
12 import "ActiveCompilerDialog"
19 import "ProjectActiveConfig"
20 import "ProjectConfig"
22 import "NodeProperties"
23 import "ProjectSettings"
35 import "BreakpointsView"
36 import "CallStackView"
47 import "FileSystemIterator"
49 #if defined(__WIN32__)
50 define pathListSep = ";";
52 define pathListSep = ":";
55 define maxPathLen = 65 * MAX_LOCATION;
57 class PathBackup : struct
64 oldPath = new char[maxPathLen];
65 oldLDPath = new char[maxPathLen];
67 GetEnvironment("PATH", oldPath, maxPathLen);
68 #if defined(__APPLE__)
69 GetEnvironment("DYLD_LIBRARY_PATH", oldLDPath, maxPathLen);
71 GetEnvironment("LD_LIBRARY_PATH", oldLDPath, maxPathLen);
77 SetEnvironment("PATH", oldPath);
78 #if defined(__APPLE__)
79 SetEnvironment("DYLD_LIBRARY_PATH", oldLDPath);
81 SetEnvironment("LD_LIBRARY_PATH", oldLDPath);
88 enum OpenCreateIfFails { no, yes, something, whatever };
89 enum OpenMethod { normal, add };
91 static Array<FileFilter> fileFilters
93 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
94 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
95 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
96 { $"Text files (*.txt, *.text, *.nfo, *.info)", "txt, text, nfo, info" },
97 { $"Web files (*.html, *.htm, *.xhtml, *.css, *.php, *.js, *.jsi, *.rb, *.xml)", "html, htm, xhtml, css, php, js, jsi, rb, xml" },
98 { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
99 { $"3D Studio Model Files (*.3ds)", "3ds" },
100 { $"All files", null }
103 static Array<FileType> fileTypes
105 { $"Based on extension", null },
108 { $"3D Studio Model", "3ds" }
111 static Array<FileFilter> projectFilters
113 { $"Project Files (*.epj)", ProjectExtension }
116 static Array<FileType> projectTypes
118 { $"Project File", ProjectExtension }
121 static Array<FileFilter> findInFilesFileFilters
123 { $"eC Files (*.ec, *.eh)", "ec, eh" },
124 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
125 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
126 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
127 { $"Text files (*.txt)", "txt" },
128 { $"All files", null }
131 FileDialog ideFileDialog
133 type = multiOpen, text = $"Open";
134 types = fileTypes.array, sizeTypes = fileTypes.count * sizeof(FileType), filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter);
137 define openProjectFileDialogTitle = $"Open Project";
138 define addProjectFileDialogTitle = $"Open Additional Project";
139 FileDialog ideProjectFileDialog
142 types = projectTypes.array, sizeTypes = projectTypes.count * sizeof(FileType), filters = projectFilters.array, sizeFilters = projectFilters.count * sizeof(FileFilter);
145 GlobalSettingsDialog globalSettingsDialog
147 ideSettings = ideSettings;
148 settingsContainer = settingsContainer;
150 void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange)
152 switch(globalSettingsChange)
157 for(child = ide.firstChild; child; child = child.next)
159 if(child._class == class(CodeEditor))
161 CodeEditor codeEditor = (CodeEditor) child;
162 codeEditor.editBox.freeCaret = ideSettings.useFreeCaret;
163 // codeEditor.editBox.lineNumbers = ideSettings.showLineNumbers;
164 codeEditor.editBox.caretFollowsScrolling = ideSettings.caretFollowsScrolling;
165 codeEditor.OnPostCreate(); // Update editBox margin size
172 case compilerSettings:
174 ide.UpdateMakefiles();
181 void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
186 lineY = (line - 1) * lineH;
187 if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
189 Bitmap bitmap = resource.bitmap;
191 surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
196 #define IDEItem(x) (&((IDEWorkSpace)0).x)
198 class IDEToolbar : ToolBar
202 ToolButton buttonNewFile { this, toolTip = $"New file", menuItemPtr = IDEItem(fileNewItem) };
204 ToolButton buttonOpenFile { this, toolTip = $"Open file", menuItemPtr = IDEItem(fileOpenItem) };
206 // ToolButton buttonCloseFile { this, toolTip = $"Close file", menuItemPtr = IDEItem(fileCloseItem) };
208 ToolButton buttonSaveFile { this, toolTip = $"Save file", menuItemPtr = IDEItem(fileSaveItem) };
210 ToolButton buttonSaveAllFile { this, toolTip = $"Save all", menuItemPtr = IDEItem(fileSaveAllItem) };
212 ToolSeparator separator1 { this };
221 // ToolSeparator separator2 { this };
223 /* Project options */
225 ToolButton buttonNewProject { this, toolTip = $"New project", menuItemPtr = IDEItem(projectNewItem) };
227 ToolButton buttonOpenProject { this, toolTip = $"Open project", menuItemPtr = IDEItem(projectOpenItem) };
228 // Add project to workspace
229 ToolButton buttonAddProject { this, toolTip = $"Add project to workspace", menuItemPtr = IDEItem(projectAddItem), disabled = true; };
231 // ToolButton buttonCloseProject { this, toolTip = $"Close project", menuItemPtr = IDEItem(projectCloseItem), disabled = true; };
233 ToolSeparator separator3 { this };
235 /* Build/Execution options */
237 ToolButton buttonBuild { this, toolTip = $"Build project", menuItemPtr = IDEItem(projectBuildItem), disabled = true; };
239 ToolButton buttonReLink { this, toolTip = $"Relink project", menuItemPtr = IDEItem(projectLinkItem), disabled = true; };
241 ToolButton buttonRebuild { this, toolTip = $"Rebuild project", menuItemPtr = IDEItem(projectRebuildItem), disabled = true; };
243 ToolButton buttonClean { this, toolTip = $"Clean project", menuItemPtr = IDEItem(projectCleanItem), disabled = true; };
245 // ToolButton buttonRealClean { this, toolTip = $"Real clean project", menuItemPtr = IDEItem(projectRealCleanItem), disabled = true; };
246 // Regenerate Makefile
247 ToolButton buttonRegenerateMakefile { this, toolTip = $"Regenerate Makefile", menuItemPtr = IDEItem(projectRegenerateItem), disabled = true; };
248 // Compile actual file
250 ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem), disabled = true; };
252 ToolSeparator separator4 { this };
256 ToolButton buttonDebugStartResume { this, toolTip = $"Start", menuItemPtr = IDEItem(debugStartResumeItem), disabled = true; };
258 ToolButton buttonDebugRestart { this, toolTip = $"Restart", menuItemPtr = IDEItem(debugRestartItem), disabled = true; };
260 ToolButton buttonDebugPause { this, toolTip = $"Break", menuItemPtr = IDEItem(debugBreakItem), disabled = true; };
262 ToolButton buttonDebugStop { this, toolTip = $"Stop", menuItemPtr = IDEItem(debugStopItem), disabled = true; };
264 //ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem) };
266 ToolButton buttonDebugStepInto { this, toolTip = $"Step Into", menuItemPtr = IDEItem(debugStepIntoItem), disabled = true; };
268 ToolButton buttonDebugStepOver { this, toolTip = $"Step Over", menuItemPtr = IDEItem(debugStepOverItem), disabled = true; };
270 ToolButton buttonDebugStepOut { this, toolTip = $"Step Out", menuItemPtr = IDEItem(debugStepOutItem), disabled = true; };
272 ToolButton buttonDebugSkipStepOver { this, toolTip = $"Step Over Skipping Breakpoints", menuItemPtr = IDEItem(debugSkipStepOverItem), disabled = true; };
275 class IDEMainFrame : Window
277 background = formColor;
278 borderStyle = sizable;
282 minClientSize = { 600, 300 };
284 icon = { ":icon.png" };
285 text = titleECEREIDE;
289 anchor = { top = 0, right = 0, bottom = 0 };
292 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
299 isActiveClient = true;
301 direction = vertical;
302 background = formColor;
303 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
311 ((IDEWorkSpace)master).toolBar = null;
314 IDEWorkSpace ideWorkSpace { stack, this, toolBar = toolBar };
317 define ide = ideMainFrame.ideWorkSpace;
319 class IDEWorkSpace : Window
321 background = Color { 85, 85, 85 };
324 hasVertScroll = true;
325 hasHorzScroll = true;
327 isActiveClient = true;
328 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
332 MenuItem * driverItems, * skinItems;
333 StatusField pos { width = 150 };
334 StatusField ovr, caps, num;
336 BitmapResource back { ":ecereBack.jpg", window = this };
337 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
338 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
339 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
340 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
341 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
342 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
343 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
344 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
345 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
346 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
348 Debugger debugger { };
350 ProjectView projectView;
352 OutputView outputView
356 void OnGotoError(char * line)
361 void OnCodeLocationParseAndGoTo(char * line)
363 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
366 bool OnKeyDown(Key key, unichar ch)
371 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
372 ide.ShowCodeEditor();
375 ide.projectView.stopBuild = true;
379 OutputView::OnKeyDown(key, ch);
386 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
389 ide.RepositionWindows(false);
393 bool OnClose(bool parentClosing)
397 ide.RepositionWindows(false);
398 return parentClosing;
402 CallStackView callStackView
404 parent = this, font = { panelFont.faceName, panelFont.size };
406 void OnGotoLine(char * line)
409 stackLvl = atoi(line);
410 ide.debugger.GoToStackFrameLine(stackLvl, true);
413 void OnSelectFrame(int lineNumber)
415 ide.debugger.SelectFrame(lineNumber);
418 void OnToggleBreakpoint()
420 Debugger debugger = ide.debugger;
421 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
423 int line = debugger.activeFrame.line;
424 char name[MAX_LOCATION];
426 // TOFIX: Improve on this, don't use only filename, make a function
427 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
428 if(ide && ide.workspace)
430 for(p : ide.workspace.projects)
432 if(p.topNode.Find(name, false))
440 for(p : ide.workspace.projects)
442 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
450 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
453 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
454 if(codeEditor) { codeEditor.Update(null); Activate(); }
459 bool OnKeyDown(Key key, unichar ch)
463 case escape: ide.ShowCodeEditor(); break;
468 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
471 ide.RepositionWindows(false);
475 bool OnClose(bool parentClosing)
479 ide.RepositionWindows(false);
480 return parentClosing;
483 void OnRedraw(Surface surface)
486 int lineCursor, lineTopFrame, activeThread, hitThread;
487 int lineH, scrollY, boxH;
489 Breakpoint bp = null;
490 Debugger debugger = ide.debugger;
491 Frame activeFrame = debugger.activeFrame;
494 scrollY = editBox.scroll.y;
495 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
497 activeThread = debugger.activeThread;
498 hitThread = debugger.hitThread;
499 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
501 if(activeFrame && activeFrame.absoluteFile)
503 for(i : ide.workspace.breakpoints; i.type == user)
505 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
506 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
507 activeFrame.line == i.line)
516 DrawLineMarginIcon(surface,
517 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
518 lineCursor /*1*/, lineH, scrollY, boxH);
521 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
522 DrawLineMarginIcon(surface,
523 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
524 1, lineH, scrollY, boxH);
526 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
527 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
528 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
530 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
531 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
532 if(editBox.horzScroll && editBox.horzScroll.visible)
534 surface.SetBackground(control);
535 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
540 WatchesView watchesView { parent = this };
541 ThreadsView threadsView
543 parent = this, font = { panelFont.faceName, panelFont.size };
545 bool OnKeyDown(Key key, unichar ch)
549 case escape: ide.ShowCodeEditor(); break;
554 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
557 ide.RepositionWindows(false);
561 bool OnClose(bool parentClosing)
565 ide.RepositionWindows(false);
566 return parentClosing;
569 void OnSelectThread(int threadId)
572 ide.debugger.SelectThread(threadId);
575 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
578 Debugger debugger = ide.debugger;
579 *activeThread = debugger.activeThread;
580 *hitThread = debugger.hitThread;
581 *signalThread = debugger.signalThread;
586 BreakpointsView breakpointsView { parent = this };
588 ToolBox toolBox { parent = this };
589 Sheet sheet { parent = this };
592 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
594 Menu fileMenu { menu, $"File", f, hasMargin = true };
597 fileMenu, $"New", n, ctrlN;
598 bitmap = { ":actions/docNew.png" };
599 bool NotifySelect(MenuItem selection, Modifiers mods)
601 Window document = (Window)NewCodeEditor(this, normal, false);
602 document.NotifySaved = DocumentSaved;
606 MenuItem fileOpenItem
608 fileMenu, $"Open...", o, ctrlO;
609 bitmap = { ":actions/docOpen.png" };
610 bool NotifySelect(MenuItem selection, Modifiers mods)
612 if(!projectView && ideSettings.ideFileDialogLocation)
613 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
616 if(ideFileDialog.Modal() == ok)
618 bool gotWhatWeWant = false;
620 int numSelections = ideFileDialog.numSelections;
621 char ** multiFilePaths = ideFileDialog.multiFilePaths;
623 for(c = 0; c < numSelections; c++)
625 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
626 gotWhatWeWant = true;
629 MessageBox { type = yesNo, master = this, text = $"Error opening file",
630 contents = $"Open a different file?" }.Modal() == no)
632 if(!projectView && gotWhatWeWant)
633 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
643 MenuItem fileCloseItem { fileMenu, $"Close", c, ctrlF4, NotifySelect = MenuFileClose };
644 MenuDivider { fileMenu };
645 MenuItem fileSaveItem { fileMenu, $"Save", s, ctrlS, bitmap = { ":actions/docSave.png" } };
646 MenuItem fileSaveAsItem { fileMenu, $"Save As...", a };
647 MenuItem fileSaveAllItem { fileMenu, $"Save All", l, NotifySelect = MenuFileSaveAll, bitmap = { ":actions/docSaveAll.png" } };
648 MenuDivider { fileMenu };
651 fileMenu, $"Find In Files...", f, Key { f, ctrl = true , shift = true };
652 bool NotifySelect(MenuItem selection, Modifiers mods)
654 findInFilesDialog.replaceMode = false;
655 findInFilesDialog.Show();
659 MenuItem replaceInFiles
661 fileMenu, $"Replace In Files...", e, Key { r, ctrl = true , shift = true };
662 bool NotifySelect(MenuItem selection, Modifiers mods)
664 findInFilesDialog.replaceMode = true;
665 findInFilesDialog.Show();
669 MenuDivider { fileMenu };
670 MenuItem globalSettingsItem
672 fileMenu, $"Global Settings...", g;
673 bool NotifySelect(MenuItem selection, Modifiers mods)
675 globalSettingsDialog.master = this;
676 if(ide.workspace && ide.workspace.compiler)
677 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
678 else if(ideSettings.defaultCompiler)
679 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
680 globalSettingsDialog.Modal();
684 MenuDivider { fileMenu };
685 Menu recentFiles { fileMenu, $"Recent Files", r };
686 Menu recentProjects { fileMenu, $"Recent Projects", p };
687 MenuDivider { fileMenu };
690 fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit;
692 bool NotifySelect(MenuItem selection, Modifiers mods)
694 ideMainFrame.Destroy(0);
699 bool FileRecentFile(MenuItem selection, Modifiers mods)
702 for(file : ideSettings.recentFiles)
704 if(id == selection.id)
706 OpenFile(file, normal, true, null, no, normal);
714 bool FileRecentProject(MenuItem selection, Modifiers mods)
717 for(file : ideSettings.recentProjects)
719 if(id == selection.id)
721 OpenFile(file, normal, true, null, no, normal);
729 MenuPlacement editMenu { menu, $"Edit", e };
731 Menu projectMenu { menu, $"Menu"."Project", p, hasMargin = true };
732 MenuItem projectNewItem
734 projectMenu, $"New...", n, Key { n, true, true };
735 bitmap = { ":actions/projNew.png" };
736 bool NotifySelect(MenuItem selection, Modifiers mods)
738 if(!DontTerminateDebugSession($"New Project"))
739 if(MenuWindowCloseAll(null, 0))
741 NewProjectDialog newProjectDialog;
745 projectView.visible = false;
746 if(!projectView.Destroy(0))
750 newProjectDialog = { master = this };
751 newProjectDialog.Modal();
754 ideSettings.AddRecentProject(projectView.fileName);
755 ide.UpdateRecentMenus();
756 settingsContainer.Save();
762 MenuItem projectOpenItem
764 projectMenu, $"Open...", o, Key { o, true, true };
765 bitmap = { ":actions/projOpen.png" };
766 bool NotifySelect(MenuItem selection, Modifiers mods)
768 if(ideSettings.ideProjectFileDialogLocation)
769 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
771 ideProjectFileDialog.text = openProjectFileDialogTitle;
772 if(ideProjectFileDialog.Modal() == ok)
774 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
775 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
780 MenuItem projectQuickItem
782 projectMenu, $"Quick...", q, f7;
783 bool NotifySelect(MenuItem selection, Modifiers mods)
786 QuickProjectDialog{ this }.Modal();
790 MenuItem projectAddItem
792 projectMenu, $"Add project to workspace...", a, Key { a, true, true };
793 bitmap = { ":actions/projAdd.png" };
795 bool NotifySelect(MenuItem selection, Modifiers mods)
797 if(ideSettings.ideProjectFileDialogLocation)
798 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
800 ideProjectFileDialog.text = addProjectFileDialogTitle;
803 if(ideProjectFileDialog.Modal() == ok)
805 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
807 if(MessageBox { type = yesNo, master = this, text = $"Error opening project file",
808 contents = $"Add a different project?" }.Modal() == no)
819 MenuItem projectCloseItem
821 projectMenu, $"Close", c, disabled = true;
822 bool NotifySelect(MenuItem selection, Modifiers mods)
826 if(!ide.DontTerminateDebugSession($"Project Close"))
828 if(findInFilesDialog)
829 findInFilesDialog.SearchStop();
830 projectView.visible = false;
831 if(projectView.Destroy(0))
832 MenuWindowCloseAll(null, 0);
834 char workingDir[MAX_LOCATION];
835 GetWorkingDir(workingDir, MAX_LOCATION);
836 findInFilesDialog.currentDirectory = workingDir;
837 ideMainFrame.text = titleECEREIDE;
844 MenuDivider { projectMenu };
845 MenuItem activeCompilerItem
847 projectMenu, $"Active Compiler...", g, /*altF5, */disabled = true;
848 bool NotifySelect(MenuItem selection, Modifiers mods)
850 projectView.MenuCompiler(null, mods);
854 MenuItem projectActiveConfigItem
856 projectMenu, $"Active Configuration...", g, altF5, disabled = true;
857 bool NotifySelect(MenuItem selection, Modifiers mods)
859 projectView.MenuConfig(projectView.active ? selection : null, mods);
863 MenuItem projectSettingsItem
865 projectMenu, $"Settings...", s, altF7, disabled = true;
866 bool NotifySelect(MenuItem selection, Modifiers mods)
868 projectView.MenuSettings(projectView.active ? selection : null, mods);
872 MenuDivider { projectMenu };
873 MenuItem projectBrowseFolderItem
875 projectMenu, $"Browse Project Folder", p, disabled = true;
876 bool NotifySelect(MenuItem selection, Modifiers mods)
879 projectView.MenuBrowseFolder(null, mods);
883 MenuDivider { projectMenu };
884 MenuItem projectRunItem
886 projectMenu, $"Run", r, ctrlF5, disabled = true;
887 bitmap = { ":actions/run.png" };
888 bool NotifySelect(MenuItem selection, Modifiers mods)
891 projectView.Run(null, mods);
895 MenuItem projectBuildItem
897 projectMenu, $"Build", b, f7, disabled = true;
898 bitmap = { ":actions/build.png" };
899 bool NotifySelect(MenuItem selection, Modifiers mods)
902 projectView.ProjectBuild(projectView.active ? selection : null, mods);
906 MenuItem projectLinkItem
908 projectMenu, $"Relink", l, disabled = true;
909 bitmap = { ":actions/relink.png" };
910 bool NotifySelect(MenuItem selection, Modifiers mods)
913 projectView.ProjectLink(projectView.active ? selection : null, mods);
917 MenuItem projectRebuildItem
919 projectMenu, $"Rebuild", d, shiftF7, disabled = true;
920 bitmap = { ":actions/rebuild.png" };
921 bool NotifySelect(MenuItem selection, Modifiers mods)
924 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
928 MenuItem projectCleanItem
930 projectMenu, $"Clean", e, disabled = true;
931 bitmap = { ":actions/clean.png" };
932 bool NotifySelect(MenuItem selection, Modifiers mods)
937 projectView.ProjectClean(projectView.active ? selection : null, mods);
942 MenuItem projectRealCleanItem
944 projectMenu, $"Real Clean", disabled = true;
945 bitmap = { ":actions/clean.png" };
946 bool NotifySelect(MenuItem selection, Modifiers mods)
951 projectView.ProjectRealClean(projectView.active ? selection : null, mods);
956 MenuItem projectRegenerateItem
958 projectMenu, $"Regenerate Makefile", m, disabled = true;
959 bitmap = { ":actions/regMakefile.png" };
960 bool NotifySelect(MenuItem selection, Modifiers mods)
963 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
967 MenuItem projectCompileItem;
968 Menu debugMenu { menu, $"Debug", d, hasMargin = true };
969 MenuItem debugStartResumeItem
971 debugMenu, $"Start", s, f5, disabled = true;
972 bitmap = { ":actions/debug.png" };
973 NotifySelect = MenuDebugStart;
975 bool MenuDebugStart(MenuItem selection, Modifiers mods)
979 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
980 if(!projectView.DebugStart())
981 debugStartResumeItem.disabled = false; // same exception
985 bool MenuDebugResume(MenuItem selection, Modifiers mods)
988 projectView.DebugResume();
991 MenuItem debugRestartItem
993 debugMenu, $"Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
994 bitmap = { ":actions/restart.png" };
995 bool NotifySelect(MenuItem selection, Modifiers mods)
998 projectView.DebugRestart();
1002 MenuItem debugBreakItem
1004 debugMenu, $"Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
1005 bitmap = { ":actions/pause.png" };
1006 bool NotifySelect(MenuItem selection, Modifiers mods)
1009 projectView.DebugBreak();
1013 MenuItem debugStopItem
1015 debugMenu, $"Stop", p, shiftF5, disabled = true;
1016 bitmap = { ":actions/stopDebug.png" };
1017 bool NotifySelect(MenuItem selection, Modifiers mods)
1020 projectView.DebugStop();
1024 MenuDivider { debugMenu };
1025 MenuItem debugStepIntoItem
1027 debugMenu, $"Step Into", i, f11, disabled = true;
1028 bitmap = { ":actions/stepInto.png" };
1029 bool NotifySelect(MenuItem selection, Modifiers mods)
1032 projectView.DebugStepInto();
1036 MenuItem debugStepOverItem
1038 debugMenu, $"Step Over", v, f10, disabled = true;
1039 bitmap = { ":actions/stepOver.png" };
1040 bool NotifySelect(MenuItem selection, Modifiers mods)
1043 projectView.DebugStepOver(false);
1047 MenuItem debugStepOutItem
1049 debugMenu, $"Step Out", o, shiftF11, disabled = true;
1050 bitmap = { ":actions/stepOut.png" };
1051 bool NotifySelect(MenuItem selection, Modifiers mods)
1054 projectView.DebugStepOut(false);
1058 MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
1059 MenuItem debugSkipStepOverItem
1061 debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
1062 bool NotifySelect(MenuItem selection, Modifiers mods)
1065 projectView.DebugStepOver(true);
1069 MenuItem debugSkipStepOutItem
1071 debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
1072 bitmap = { ":actions/skipBreaks.png" };
1073 bool NotifySelect(MenuItem selection, Modifiers mods)
1076 projectView.DebugStepOut(true);
1080 MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
1081 //MenuDivider { debugMenu };
1082 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
1083 MenuPlacement imageMenu { menu, $"Image", i };
1084 Menu viewMenu { menu, $"View", v };
1085 MenuItem viewProjectItem
1087 viewMenu, $"Project View", j, alt0, disabled = true;
1088 bool NotifySelect(MenuItem selection, Modifiers mods)
1092 projectView.visible = true;
1093 projectView.Activate();
1098 MenuPlacement { viewMenu, $"View Designer" };
1099 MenuPlacement { viewMenu, $"View Code" };
1100 MenuPlacement { viewMenu, $"View Properties" };
1101 MenuPlacement { viewMenu, $"View Methods" };
1102 MenuItem viewDesignerItem
1104 viewMenu, $"View Designer", d, f8;
1105 bool NotifySelect(MenuItem selection, Modifiers mods)
1107 Window client = activeClient;
1108 Class dataType = client._class;
1109 if(!strcmp(dataType.name, "Designer"))
1111 client.visible = true;
1115 ((CodeEditor)client).ViewDesigner();
1119 MenuItem viewCodeItem
1121 viewMenu, $"View Code", c, f8;
1122 bool NotifySelect(MenuItem selection, Modifiers mods)
1124 Window client = activeClient;
1125 Class dataType = client._class;
1126 if(!strcmp(dataType.name, "Designer"))
1127 client = ((Designer)client).codeEditor;
1130 // Do this after so the caret isn't moved yet...
1131 client.visible = true;
1135 MenuItem viewPropertiesItem
1137 viewMenu, $"View Properties", p, f4;
1138 bool NotifySelect(MenuItem selection, Modifiers mods)
1140 sheet.visible = true;
1141 sheet.sheetSelected = properties;
1146 MenuItem viewMethodsItem
1148 viewMenu, $"View Methods", m, f4;
1149 bool NotifySelect(MenuItem selection, Modifiers mods)
1151 sheet.visible = true;
1152 sheet.sheetSelected = methods;
1157 MenuItem viewToolBoxItem
1159 viewMenu, $"View Toolbox", x, f12;
1160 bool NotifySelect(MenuItem selection, Modifiers mods)
1162 toolBox.visible = true;
1167 MenuItem viewOutputItem
1169 viewMenu, $"Output", o, alt2;
1170 bool NotifySelect(MenuItem selection, Modifiers mods)
1176 MenuItem viewWatchesItem
1178 viewMenu, $"Watches", w, alt3;
1179 bool NotifySelect(MenuItem selection, Modifiers mods)
1185 MenuItem viewThreadsItem
1187 viewMenu, $"Threads", t, alt4;
1188 bool NotifySelect(MenuItem selection, Modifiers mods)
1194 MenuItem viewBreakpointsItem
1196 viewMenu, $"Breakpoints", b, alt5;
1197 bool NotifySelect(MenuItem selection, Modifiers mods)
1199 breakpointsView.Show();
1203 MenuItem viewCallStackItem
1205 viewMenu, $"Call Stack", s, alt7;
1206 bool NotifySelect(MenuItem selection, Modifiers mods)
1208 callStackView.Show();
1212 MenuItem viewAllDebugViews
1214 viewMenu, $"All Debug Views", a, alt9;
1215 bool NotifySelect(MenuItem selection, Modifiers mods)
1220 callStackView.Show();
1221 breakpointsView.Show();
1225 #ifdef GDB_DEBUG_GUI
1226 MenuDivider { viewMenu };
1227 MenuItem viewGDBItem
1229 viewMenu, $"GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1230 bool NotifySelect(MenuItem selection, Modifiers mods)
1237 MenuDivider { viewMenu };
1238 MenuItem viewColorPicker
1240 viewMenu, $"Color Picker...", c, Key { c, ctrl = true , shift = true };
1241 bool NotifySelect(MenuItem selection, Modifiers mods)
1243 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1244 colorPicker.Create();
1248 MenuDivider { viewMenu };
1252 viewMenu, "Full Screen", f, checkable = true;
1254 bool NotifySelect(MenuItem selection, Modifiers mods)
1256 app.fullScreen ^= true;
1258 anchor = { 0, 0, 0, 0 };
1263 Menu driversMenu { viewMenu, $"Graphics Driver", v };
1264 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1265 Menu windowMenu { menu, $"Window", w };
1266 MenuItem { windowMenu, $"Close All", l, NotifySelect = MenuWindowCloseAll };
1267 MenuDivider { windowMenu };
1268 MenuItem { windowMenu, $"Next", n, f6, NotifySelect = MenuWindowNext };
1269 MenuItem { windowMenu, $"Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1270 MenuDivider { windowMenu };
1271 MenuItem { windowMenu, $"Cascade", c, NotifySelect = MenuWindowCascade };
1272 MenuItem { windowMenu, $"Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1273 MenuItem { windowMenu, $"Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1274 MenuItem { windowMenu, $"Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1275 MenuDivider { windowMenu };
1276 MenuItem { windowMenu, $"Windows...", w, NotifySelect = MenuWindowWindows };
1277 Menu helpMenu { menu, $"Help", h };
1280 helpMenu, $"API Reference", r, f1;
1281 bool NotifySelect(MenuItem selection, Modifiers mods)
1283 Execute("documentor");
1287 MenuDivider { helpMenu };
1290 helpMenu, $"About...", a;
1291 bool NotifySelect(MenuItem selection, Modifiers mods)
1293 AboutIDE { master = this }.Modal();
1298 property ToolBox toolBox
1300 get { return toolBox; }
1303 property Sheet sheet
1305 get { return sheet; }
1308 property Project project
1310 get { return projectView ? projectView.project : null; }
1313 property Workspace workspace
1315 get { return projectView ? projectView.workspace : null; }
1318 FindInFilesDialog findInFilesDialog
1320 master = this, parent = this;
1321 filters = findInFilesFileFilters.array, sizeFilters = findInFilesFileFilters.count * sizeof(FileFilter);
1325 #ifdef GDB_DEBUG_GUI
1328 master = this, parent = this;
1329 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1331 void OnCommand(char * string)
1334 ide.debugger.SendGDBCommand(string);
1339 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1341 //app.driver = app.drivers[selection.id];
1343 app.driver = selection.id ? "OpenGL" : "X";
1345 app.driver = selection.id ? "OpenGL" : "GDI";
1347 delete ideSettings.displayDriver;
1348 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1350 settingsContainer.Save();
1351 //SetDriverAndSkin();
1355 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1357 app.skin = app.skins[selection.id];
1362 void SetDriverAndSkin()
1365 for(c = 0; c < app.numSkins; c++)
1366 if(!strcmp(app.skins[c], app.skin))
1368 skinItems[c].checked = true;
1371 for(c = 0; c < app.numDrivers; c++)
1372 if(!strcmp(app.drivers[c], app.driver))
1374 driverItems[c].checked = true;
1379 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1381 Project project = workspace.projects.firstIterator.data;
1382 projectView = ProjectView
1385 fileName = fileName;
1387 void NotifyDestroyed(Window window, DialogResult result)
1390 text = titleECEREIDE;
1395 projectView.Create();
1396 RepositionWindows(false);
1398 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1399 projectView.workspace = workspace;
1400 projectView.project = project;
1401 ideMainFrame.SetText("%s - %s", project.topNode.name, titleECEREIDE);
1405 ide.breakpointsView.LoadFromWorkspace();
1406 ide.watchesView.LoadFromWorkspace();
1408 findInFilesDialog.projectNodeField.userData = projectView;
1411 char fileName[MAX_LOCATION];
1412 strcpy(fileName, project.topNode.path);
1413 PathCat(fileName, project.topNode.name);
1418 bool GetDebugMenusDisabled()
1422 Project project = projectView.project;
1424 if(project.GetTargetType(project.config) == executable)
1431 void RepositionWindows(bool expand)
1436 bool inDebugMode = debugger.isActive;
1437 bool callStackVisible = expand ? false : callStackView.visible;
1438 bool threadsVisible = expand ? false : threadsView.visible;
1439 bool watchesVisible = expand ? false : watchesView.visible;
1440 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1441 bool toolBoxVisible = toolBox.visible;
1442 bool outputVisible = expand ? false : outputView.visible;
1443 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1444 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1446 for(child = firstChild; child; child = child.next)
1448 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1449 child._class == class(Sheet) || child._class == class(ProjectView))
1451 Anchor anchor = child.anchor;
1452 anchor.top = topDistance;
1453 anchor.bottom = bottomDistance;
1454 if(child._class == class(CodeEditor) || child._class == class(Designer))
1456 anchor.right = toolBoxVisible ? 150 : 0;
1458 child.anchor = anchor;
1462 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1463 child._class == class(BreakpointsView))
1464 child.visible = false;
1467 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1472 bool ShowCodeEditor()
1475 activeClient.Activate();
1476 else if(projectView)
1478 projectView.visible = true;
1479 projectView.Activate();
1483 sheet.visible = true;
1489 bool ShouldStopBuild()
1491 return projectView.stopBuild;
1494 void DocumentSaved(Window document, char * fileName)
1496 ideSettings.AddRecentFile(fileName);
1497 ide.UpdateRecentMenus();
1498 settingsContainer.Save();
1501 bool Window::OnFileModified(FileChange fileChange, char * param)
1504 sprintf(temp, $"The document %s was modified by another application.\n"
1505 "Would you like to reload it and lose your changes?", this.fileName);
1506 if(MessageBox { type = yesNo, master = this/*.parent*/,
1507 text = $"Document has been modified", contents = temp }.Modal() == yes)
1509 char * fileName = CopyString(this.fileName);
1510 WindowState state = this.state;
1511 Anchor anchor = this.anchor;
1512 Size size = this.size;
1514 this.modifiedDocument = false;
1516 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1519 this.anchor = anchor;
1521 this.SetState(state, true, 0);
1529 void UpdateMakefiles()
1533 for(prj : workspace.projects)
1535 bool first = prj == workspace.projects.firstIterator.data;
1536 projectView.ProjectUpdateMakefileForAllConfigs(prj, first, first);
1543 bool unavailable = !project;
1545 projectQuickItem.disabled = !unavailable;
1547 projectAddItem.disabled = unavailable;
1548 toolBar.buttonAddProject.disabled = unavailable;
1550 activeCompilerItem.disabled = unavailable;
1551 projectActiveConfigItem.disabled = unavailable;
1552 projectSettingsItem.disabled = unavailable;
1554 projectBrowseFolderItem.disabled = unavailable;
1556 viewProjectItem.disabled = unavailable;
1562 void AdjustBuildMenus()
1564 bool unavailable = project && projectView.buildInProgress;
1566 projectNewItem.disabled = unavailable;
1567 toolBar.buttonNewProject.disabled = unavailable;
1568 projectOpenItem.disabled = unavailable;
1569 toolBar.buttonOpenProject.disabled = unavailable;
1571 unavailable = !project || projectView.buildInProgress;
1573 projectCloseItem.disabled = unavailable;
1574 // toolBar.buttonCloseProject.disabled = unavailable;
1576 projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
1577 toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
1578 projectBuildItem.disabled = unavailable;
1579 toolBar.buttonBuild.disabled = unavailable;
1580 projectLinkItem.disabled = unavailable;
1581 toolBar.buttonReLink.disabled = unavailable;
1582 projectRebuildItem.disabled = unavailable;
1583 toolBar.buttonRebuild.disabled = unavailable;
1584 projectCleanItem.disabled = unavailable;
1585 toolBar.buttonClean.disabled = unavailable;
1586 projectRealCleanItem.disabled = unavailable;
1587 // toolBar.buttonRealClean.disabled = unavailable;
1588 projectRegenerateItem.disabled = unavailable;
1589 toolBar.buttonRegenerateMakefile.disabled = unavailable;
1590 projectCompileItem.disabled = unavailable;
1593 void AdjustDebugMenus()
1595 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1596 projectView.buildInProgress == buildingMainProject;
1597 bool active = ide.debugger.isActive;
1598 bool executing = ide.debugger.state == running;
1599 //bool holding = ide.debugger.state == stopped;
1601 debugStartResumeItem.disabled = unavailable || executing;
1602 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1603 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1606 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1607 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1610 debugBreakItem.disabled = unavailable || !executing;
1611 debugStopItem.disabled = unavailable || !active;
1612 debugRestartItem.disabled = unavailable || !active;
1615 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1616 toolBar.buttonDebugStop.disabled = unavailable || !active;
1617 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1620 debugStepIntoItem.disabled = unavailable || executing;
1621 debugStepOverItem.disabled = unavailable || executing;
1622 debugStepOutItem.disabled = unavailable || executing || !active;
1623 debugSkipStepOverItem.disabled = unavailable || executing;
1624 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1627 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1628 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1629 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1630 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1631 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1633 if((Designer)GetActiveDesigner())
1635 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1638 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1639 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1644 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1646 char tempString[MAX_LOCATION];
1647 strcpy(tempString, directory);
1648 if(saveSettings && !projectView)
1650 ideSettings.ideFileDialogLocation = directory;
1651 settingsContainer.Save();
1654 ideFileDialog.currentDirectory = tempString;
1655 codeEditorFileDialog.currentDirectory = tempString;
1656 codeEditorFormFileDialog.currentDirectory = tempString;
1659 void ChangeProjectFileDialogDirectory(char * directory)
1661 ideSettings.ideProjectFileDialogLocation = directory;
1662 settingsContainer.Save();
1665 Window FindWindow(char * filePath)
1667 Window document = null;
1669 // TOCHECK: Do we need to change slashes here?
1670 for(document = firstChild; document; document = document.next)
1672 char * fileName = document.fileName;
1673 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1675 document.visible = true;
1676 document.Activate();
1683 bool DontTerminateDebugSession(char * title)
1685 if(debugger.isActive)
1687 if(MessageBox { type = yesNo, master = ide,
1688 contents = $"Do you want to terminate the debugging session in progress?",
1689 text = title }.Modal() == no)
1692 MessageBox msg { type = yesNo, master = ide,
1693 contents = "Do you want to terminate the debugging session in progress?",
1695 if(msg.Modal() == no)
1707 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1709 char extension[MAX_EXTENSION] = "";
1710 Window document = null;
1711 bool isProject = false;
1712 bool needFileModified = true;
1713 char winFilePath[MAX_LOCATION];
1714 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1718 GetExtension(filePath, extension);
1722 strcpy(extension, type);
1724 if(strcmp(extension, ProjectExtension))
1726 for(document = firstChild; document; document = document.next)
1728 char * fileName = document.fileName;
1729 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1731 document.visible = true;
1733 document.Activate();
1739 if(createIfFails == whatever)
1741 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1743 if(openMethod == normal)
1745 if(DontTerminateDebugSession($"Open Project"))
1748 if(MenuWindowCloseAll(null, 0))
1752 projectView.visible = false;
1753 projectView.Destroy(0);
1754 // Where did this come from? projectView = null;
1761 Workspace workspace = null;
1763 if(FileExists(filePath))
1765 if(!strcmp(extension, ProjectExtension))
1767 char workspaceFile[MAX_LOCATION];
1768 strcpy(workspaceFile, filePath);
1769 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1770 workspace = LoadWorkspace(workspaceFile, filePath);
1772 else if(!strcmp(extension, WorkspaceExtension))
1773 workspace = LoadWorkspace(filePath, null);
1776 //project = LoadProject(filePath);
1781 char absolutePath[MAX_LOCATION];
1782 CreateProjectView(workspace, filePath);
1783 document = projectView;
1785 workspace.DropInvalidBreakpoints();
1788 ide.projectView.ShowOutputBuildLog(true);
1790 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1791 ide.projectView.DisplayCompiler(compiler, false);
1796 char newWorkingDir[MAX_LOCATION];
1797 StripLastDirectory(filePath, newWorkingDir);
1798 ChangeFileDialogsDirectory(newWorkingDir, false);
1801 document.fileName = filePath;
1803 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1805 // this crashes on starting ide with epj file, solution please?
1806 // app.UpdateDisplay();
1808 workspace.holdTracking = true;
1809 for(ofi : workspace.openedFiles)
1811 if(ofi.state != closed)
1813 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1816 char fileName[MAX_LOCATION];
1818 GetLastDirectory(ofi.path, fileName);
1819 node = projectView.project.topNode.Find(fileName, true);
1821 node.EnsureVisible();
1825 workspace.holdTracking = false;
1827 workspace.timer.Start();
1829 findInFilesDialog.mode = FindInFilesMode::project;
1830 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1833 char location[MAX_LOCATION];
1834 StripLastDirectory(ide.project.topNode.path, location);
1835 ChangeProjectFileDialogDirectory(location);
1839 if(projectView.debugger)
1840 projectView.debugger.EvaluateWatches();
1847 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1849 ideProjectFileDialog.text = openProjectFileDialogTitle;
1850 if(ideProjectFileDialog.Modal() == cancel)
1852 filePath = ideProjectFileDialog.filePath;
1853 GetExtension(filePath, extension);
1864 else if(openMethod == add)
1869 char slashFilePath[MAX_LOCATION];
1870 GetSlashPathBuffer(slashFilePath, filePath);
1871 for(p : workspace.projects)
1873 if(!fstrcmp(p.filePath, slashFilePath))
1881 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1882 contents = $"This project is already present in workspace." }.Modal();
1886 prj = LoadProject(filePath);
1889 workspace.projects.Add(prj);
1891 projectView.AddNode(prj.topNode, null);
1892 workspace.modified = true;
1894 findInFilesDialog.AddProjectItem(prj);
1895 projectView.ProjectUpdateMakefileForAllConfigs(prj, true, true);
1898 char location[MAX_LOCATION];
1899 StripLastDirectory(prj.topNode.path, location);
1900 ChangeProjectFileDialogDirectory(location);
1903 // projectView is associated with the main project and not with the one just added but
1904 return projectView; // just to let the caller know something was opened
1912 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1913 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1914 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1916 if(FileExists(filePath))
1917 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1918 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1919 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1922 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1925 else if(!strcmp(extension, "3ds"))
1927 if(FileExists(filePath))
1928 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1929 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1930 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1934 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1937 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1938 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1939 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1940 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1941 !strcmp(extension, "js"))
1943 CodeEditor editor { parent = this, state = state, visible = false };
1944 editor.updatingCode = true;
1945 if(editor.LoadFile(filePath))
1948 editor.visible = true;
1952 needFileModified = false;
1956 CodeEditor editor { parent = this, state = state, visible = false };
1957 if(editor.LoadFile(filePath))
1960 editor.visible = true;
1964 needFileModified = false;
1967 if(document && (document._class == class(PictureEdit) ||
1968 document._class == class(ModelView)))
1973 document.fileName = filePath;
1974 if(workspace && !workspace.holdTracking)
1975 workspace.UpdateOpenedFileInfo(filePath, opened);
1979 if(!document && createIfFails != no)
1981 if(createIfFails != yes && !needFileModified &&
1982 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
1983 createIfFails = yes;
1984 if(createIfFails == yes || createIfFails == whatever)
1986 document = (Window)NewCodeEditor(this, state, true);
1988 document.fileName = filePath;
1994 if(projectView && document._class == class(CodeEditor) && workspace)
1996 int lineNumber, position;
1998 CodeEditor editor = (CodeEditor)document;
1999 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2000 editor.openedFileInfo.holdTracking = true;
2001 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2002 position = Max(editor.openedFileInfo.position - 1, 0);
2003 editor.editBox.GoToLineNum(lineNumber);
2004 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2005 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2006 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2007 editor.editBox.scroll = scroll;
2008 editor.openedFileInfo.holdTracking = false;
2011 if(needFileModified)
2012 document.OnFileModified = OnFileModified;
2013 document.NotifySaved = DocumentSaved;
2016 ideSettings.AddRecentProject(document.fileName);
2018 ideSettings.AddRecentFile(document.fileName);
2019 ide.UpdateRecentMenus();
2020 settingsContainer.Save();
2028 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2029 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2031 if(!parentClosing && ide.workspace)
2032 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2035 bool ModelView::ModelViewOnClose(bool parentClosing)
2037 if(!parentClosing && ide.workspace)
2038 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2041 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2043 if(!parentClosing && ide.workspace)
2044 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2049 void OnUnloadGraphics(Window window)
2051 display.ClearMaterials();
2052 display.ClearTextures();
2053 display.ClearMeshes();
2057 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2059 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2060 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2064 bool OnKeyDown(Key key, unichar ch)
2069 projectView.Update(null);
2072 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2075 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2081 void GoToError(const char * line)
2084 projectView.GoToError(line);
2087 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2090 char *colon = strchr(text, ':');
2091 char filePath[MAX_LOCATION];
2092 char completePath[MAX_LOCATION];
2093 int line = 0, col = 0;
2098 char * close = strchr(text, ')');
2102 strncpy(name, &text[4], close - text - 4);
2103 name[close - text - 4] = '\0';
2104 for(p : ide.workspace.projects)
2106 if(!strcmp(p.name, name))
2116 prj = project ? project : (dir ? null : ide.project);
2117 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2119 path = (colon - 1 > path) ? colon - 1 : path;
2120 colon = strstr(colon + 1, ":");
2122 while(isspace(*path)) path++;
2125 strncpy(filePath, path, colon - path);
2126 filePath[colon - path] = '\0';
2127 line = atoi(colon + 1);
2128 colon = strstr(colon + 1, ":");
2130 col = atoi(colon + 1);
2132 else if(path - 1 >= path && *(path - 1) == '\"')
2134 colon = strchr(path, '\"');
2137 strncpy(filePath, path, colon - path);
2138 filePath[colon - path] = '\0';
2143 strcpy(completePath, prj.topNode.path);
2144 else if(dir && dir[0])
2145 strcpy(completePath, dir);
2147 completePath[0] = '\0';
2148 PathCat(completePath, filePath);
2150 if(FileExists(completePath).isFile)
2152 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2153 if(codeEditor && line)
2155 EditBox editBox = codeEditor.editBox;
2156 editBox.GoToLineNum(line - 1);
2157 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2162 void OnRedraw(Surface surface)
2164 Bitmap bitmap = back.bitmap;
2166 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2169 void SheetSelected(SheetType sheetSelected)
2171 if(activeChild == sheet)
2173 if(sheetSelected == methods)
2175 viewPropertiesItem.accelerator = f4;
2176 viewPropertiesItem.parent = viewMenu;
2177 viewMethodsItem.parent = null;
2181 viewMethodsItem.accelerator = f4;
2182 viewMethodsItem.parent = viewMenu;
2183 viewPropertiesItem.parent = null;
2188 viewMethodsItem.parent = viewMenu;
2189 viewPropertiesItem.parent = viewMenu;
2190 if(sheetSelected == methods)
2192 viewMethodsItem.accelerator = f4;
2193 viewPropertiesItem.accelerator = 0;
2197 viewMethodsItem.accelerator = 0;
2198 viewPropertiesItem.accelerator = f4;
2203 void OnActivateClient(Window client, Window previous)
2205 //if(!client || client != previous)
2208 if(!client || client != previous)
2211 dataType = previous._class;
2212 if(previous && !strcmp(dataType.name, "CodeEditor"))
2214 ((CodeEditor)previous).UpdateFormCode();
2216 else if(previous && !strcmp(dataType.name, "Designer"))
2218 ((Designer)previous).codeEditor.UpdateFormCode();
2223 dataType = client._class;
2224 if(client && !strcmp(dataType.name, "CodeEditor"))
2226 CodeEditor codeEditor = (CodeEditor)client;
2227 SetPrivateModule(codeEditor.privateModule);
2228 SetCurrentContext(codeEditor.globalContext);
2229 SetTopContext(codeEditor.globalContext);
2230 SetGlobalContext(codeEditor.globalContext);
2232 SetDefines(&codeEditor.defines);
2233 SetImports(&codeEditor.imports);
2235 SetActiveDesigner(codeEditor.designer);
2237 sheet.codeEditor = codeEditor;
2238 toolBox.codeEditor = codeEditor;
2240 viewDesignerItem.parent = viewMenu;
2241 if(activeChild != codeEditor)
2243 viewCodeItem.parent = viewMenu;
2244 viewDesignerItem.accelerator = 0;
2245 viewCodeItem.accelerator = f8;
2249 viewCodeItem.parent = null;
2250 viewDesignerItem.accelerator = f8;
2253 else if(client && !strcmp(dataType.name, "Designer"))
2255 CodeEditor codeEditor = ((Designer)client).codeEditor;
2258 SetPrivateModule(codeEditor.privateModule);
2259 SetCurrentContext(codeEditor.globalContext);
2260 SetTopContext(codeEditor.globalContext);
2261 SetGlobalContext(codeEditor.globalContext);
2262 SetDefines(&codeEditor.defines);
2263 SetImports(&codeEditor.imports);
2267 SetPrivateModule(null);
2268 SetCurrentContext(null);
2269 SetTopContext(null);
2270 SetGlobalContext(null);
2275 SetActiveDesigner((Designer)client);
2277 sheet.codeEditor = codeEditor;
2278 toolBox.codeEditor = codeEditor;
2280 viewCodeItem.parent = viewMenu;
2281 if(activeChild != client)
2283 viewDesignerItem.parent = viewMenu;
2284 viewDesignerItem.accelerator = f8;
2285 viewCodeItem.accelerator = 0;
2289 viewDesignerItem.parent = null;
2290 viewCodeItem.accelerator = f8;
2296 sheet.codeEditor = null;
2297 toolBox.codeEditor = null;
2298 SetActiveDesigner(null);
2300 viewDesignerItem.parent = null;
2301 viewCodeItem.parent = null;
2304 SheetSelected(sheet.sheetSelected);
2307 projectCompileItem = null;
2312 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2314 CodeEditor codeEditor = (CodeEditor)client;
2315 EditBox editBox = codeEditor.editBox;
2317 statusBar.AddField(pos);
2319 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2320 statusBar.AddField(caps);
2322 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2323 statusBar.AddField(ovr);
2325 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2326 statusBar.AddField(num);
2328 //statusBar.text = "Ready";
2330 if(projectView && projectView.project)
2332 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2336 sprintf(name, $"Compile %s", node.name);
2337 projectCompileItem =
2339 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2341 bool NotifySelect(MenuItem selection, Modifiers mods)
2345 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2347 projectView.Compile(node);
2352 projectMenu.AddDynamic(projectCompileItem, ide, false);
2358 caps = ovr = num = null;
2363 bool OnClose(bool parentClosing)
2365 //return !projectView.buildInProgress;
2366 if(projectView && projectView.buildInProgress)
2368 if(DontTerminateDebugSession($"Close IDE"))
2370 if(findInFilesDialog)
2371 findInFilesDialog.SearchStop();
2374 workspace.timer.Stop();
2377 ideMainFrame.Destroy(0);
2384 for(c = 1; c<app.argc; c++)
2386 char fullPath[MAX_LOCATION];
2387 char parentPath[MAX_LOCATION];
2388 char ext[MAX_EXTENSION];
2390 FileAttribs dirAttribs;
2391 GetWorkingDir(fullPath, MAX_LOCATION);
2392 PathCat(fullPath, app.argv[c]);
2393 StripLastDirectory(fullPath, parentPath);
2394 GetExtension(app.argv[c], ext);
2395 isProject = !strcmpi(ext, "epj");
2397 if(isProject && c > 1) continue;
2399 // Create directory for projects (only)
2400 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2402 if(isProject && !FileExists(fullPath))
2404 // The NewProject will handle directory creation
2405 /*if(!dirAttribs.isDirectory)
2407 MakeDir(parentPath);
2408 dirAttribs = FileExists(parentPath);
2410 if(dirAttribs.isDirectory)*/
2412 char name[MAX_LOCATION];
2413 NewProjectDialog newProjectDialog;
2417 projectView.visible = false;
2418 if(!projectView.Destroy(0))
2422 newProjectDialog = { master = this };
2424 strcpy(name, app.argv[c]);
2425 StripExtension(name);
2426 GetLastDirectory(name, name);
2427 newProjectDialog.projectName.contents = name;
2428 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2429 newProjectDialog.locationEditBox.path = parentPath;
2430 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2432 newProjectDialog.Modal();
2435 ideSettings.AddRecentProject(projectView.fileName);
2436 ide.UpdateRecentMenus();
2437 settingsContainer.Save();
2440 // Open only one project
2444 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2452 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2455 projectView.visible = false;
2456 projectView.Destroy(0);
2459 #ifdef GDB_DEBUG_GUI
2460 gdbDialog.Destroy(0);
2465 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2469 char * oldPaths[128];
2470 String oldList = new char[maxPathLen];
2471 Array<String> newExePaths { };
2472 //Map<String, bool> exePathExists { };
2474 #if defined(__unix__) || defined(__APPLE__)
2475 Array<String> newLibPaths { };
2476 Map<String, bool> libPathExists { };
2481 for(prj : workspace.projects)
2483 DirExpression targetDirExp;
2485 // SKIP FIRST PROJECT...
2486 if(prj == workspace.projects.firstIterator.data) continue;
2488 // NOTE: Right now the additional project config dir will be
2489 // obtained when the debugger is started, so toggling it
2490 // while building will change which library gets used.
2491 // To go with the initial state, e.g. when F5 was pressed,
2492 // we nould need to keep a list of all project's active
2493 // config upon startup.
2494 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2496 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2500 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2501 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2505 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2506 if(cfg.targetType == sharedLibrary && cfg.debug)
2510 if(targetDirExp.dir)
2512 char buffer[MAX_LOCATION];
2513 #if defined(__WIN32__)
2514 Array<String> paths = newExePaths;
2516 Array<String> paths = newLibPaths;
2518 GetSystemPathBuffer(buffer, prj.topNode.path);
2519 PathCat(buffer, targetDirExp.dir);
2522 if(!fstrcmp(p, buffer))
2529 paths.Add(CopyString(buffer));
2531 delete targetDirExp;
2535 for(item : compiler.executableDirs)
2538 for(p : newExePaths)
2540 if(!fstrcmp(p, item))
2547 newExePaths.Add(CopySystemPath(item));
2550 GetEnvironment("PATH", oldList, maxPathLen);
2552 printf("Old value of PATH: %s\n", oldList);
2554 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2555 for(c = 0; c < count; c++)
2558 for(p : newExePaths)
2560 if(!fstrcmp(p, oldPaths[c]))
2567 newExePaths.Add(CopySystemPath(oldPaths[c]));
2571 for(path : newExePaths)
2572 len += strlen(path) + 1;
2573 newList = new char[len + 1];
2575 for(path : newExePaths)
2577 strcat(newList, path);
2578 strcat(newList, pathListSep);
2580 newList[len - 1] = '\0';
2581 SetEnvironment("PATH", newList);
2583 printf("New value of PATH: %s\n", newList);
2590 #if defined(__unix__) || defined(__APPLE__)
2592 for(item : compiler.libraryDirs)
2594 if(!libPathExists[item]) // fstrcmp should be used
2596 newLibPaths.Add(item);
2597 libPathExists[item] = true;
2601 #if defined(__APPLE__)
2602 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2604 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2607 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2609 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2610 for(c = 0; c < count; c++)
2612 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2614 newLibPaths.Add(oldPaths[c]);
2615 libPathExists[oldPaths[c]] = true;
2620 for(path : newLibPaths)
2621 len += strlen(path) + 1;
2622 newList = new char[len + 1];
2624 for(path : newLibPaths)
2626 strcat(newList, path);
2627 strcat(newList, pathListSep);
2629 newList[len - 1] = '\0';
2630 #if defined(__APPLE__)
2631 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2633 SetEnvironment("LD_LIBRARY_PATH", newList);
2636 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2641 delete libPathExists;
2644 if(compiler.distccEnabled && compiler.distccHosts)
2645 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2650 void DestroyTemporaryProjectDir()
2652 if(tmpPrjDir && tmpPrjDir[0])
2654 if(FileExists(tmpPrjDir).isDirectory)
2655 DestroyDir(tmpPrjDir);
2656 property::tmpPrjDir = null;
2662 // Graphics Driver Menu
2666 app.currentSkin.selectionColor = selectionColor;
2667 app.currentSkin.selectionText = selectionText;
2671 driverItems = new MenuItem[app.numDrivers];
2672 for(c = 0; c < app.numDrivers; c++)
2674 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2675 driverItems[c].id = c;
2676 driverItems[c].isRadio = true;
2679 driverItems = new MenuItem[2];
2680 #if defined(__unix__)
2681 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2682 driverItems[0].id = 0;
2683 driverItems[0].isRadio = true;
2685 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2686 driverItems[0].id = 0;
2687 driverItems[0].isRadio = true;
2689 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2690 driverItems[1].id = 1;
2691 driverItems[1].isRadio = true;
2693 /* skinItems = new MenuItem[app.numSkins];
2694 for(c = 0; c < app.numSkins; c++)
2696 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2697 skinItems[c].id = c;
2698 skinItems[c].isRadio = true;
2701 ideFileDialog.master = this;
2702 ideProjectFileDialog.master = this;
2704 //SetDriverAndSkin();
2708 void UpdateRecentMenus()
2711 Menu fileMenu = menu.FindMenu($"File");
2712 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2713 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2714 char itemName[MAX_LOCATION + 4];
2717 recentFiles.Clear();
2720 for(recent : ideSettings.recentFiles)
2722 sprintf(itemName, "%d %s", 1 + c, recent);
2723 MakeSystemPath(itemName);
2724 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2728 recentProjects.Clear();
2730 for(recent : ideSettings.recentProjects)
2732 sprintf(itemName, "%d %s", 1 + c, recent);
2733 MakeSystemPath(itemName);
2734 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2747 void DestroyDir(char * path)
2749 RecursiveDeleteFolderFSI fsi { };
2754 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2756 bool preserveRootFolder;
2758 void OutFolder(char * folderPath, bool isRoot)
2760 if(!(preserveRootFolder && isRoot))
2761 RemoveDir(folderPath);
2764 bool OnFile(char * filePath)
2766 DeleteFile(filePath);
2771 class IDEApp : GuiApplication
2773 //driver = "Win32Console";
2774 // driver = "OpenGL";
2779 SetLoggingMode(stdOut, null);
2780 //SetLoggingMode(debug, null);
2782 settingsContainer.Load();
2783 #if defined(__unix__) || defined(__APPLE__)
2784 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2786 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2788 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2792 desktop.text = titleECEREIDE;
2795 for(c = 1; c<app.argc; c++)
2797 char fullPath[MAX_LOCATION];
2798 GetWorkingDir(fullPath, MAX_LOCATION);
2799 PathCat(fullPath, app.argv[c]);
2800 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2807 IDEMainFrame ideMainFrame { };
2809 define app = ((IDEApp)__thisModule);
2811 define titleECEREIDE = $"ECERE IDE (Debug)";
2813 define titleECEREIDE = $"ECERE IDE";