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 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1534 projectView.ShowOutputBuildLog(true);
1535 projectView.DisplayCompiler(compiler, false);
1536 for(prj : workspace.projects)
1537 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1544 bool unavailable = !project;
1546 projectQuickItem.disabled = !unavailable;
1548 projectAddItem.disabled = unavailable;
1549 toolBar.buttonAddProject.disabled = unavailable;
1551 activeCompilerItem.disabled = unavailable;
1552 projectActiveConfigItem.disabled = unavailable;
1553 projectSettingsItem.disabled = unavailable;
1555 projectBrowseFolderItem.disabled = unavailable;
1557 viewProjectItem.disabled = unavailable;
1563 void AdjustBuildMenus()
1565 bool unavailable = project && projectView.buildInProgress;
1567 projectNewItem.disabled = unavailable;
1568 toolBar.buttonNewProject.disabled = unavailable;
1569 projectOpenItem.disabled = unavailable;
1570 toolBar.buttonOpenProject.disabled = unavailable;
1572 unavailable = !project || projectView.buildInProgress;
1574 projectCloseItem.disabled = unavailable;
1575 // toolBar.buttonCloseProject.disabled = unavailable;
1577 projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
1578 toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
1579 projectBuildItem.disabled = unavailable;
1580 toolBar.buttonBuild.disabled = unavailable;
1581 projectLinkItem.disabled = unavailable;
1582 toolBar.buttonReLink.disabled = unavailable;
1583 projectRebuildItem.disabled = unavailable;
1584 toolBar.buttonRebuild.disabled = unavailable;
1585 projectCleanItem.disabled = unavailable;
1586 toolBar.buttonClean.disabled = unavailable;
1587 projectRealCleanItem.disabled = unavailable;
1588 // toolBar.buttonRealClean.disabled = unavailable;
1589 projectRegenerateItem.disabled = unavailable;
1590 toolBar.buttonRegenerateMakefile.disabled = unavailable;
1591 projectCompileItem.disabled = unavailable;
1593 if(projectView && projectView.popupMenu && projectView.popupMenu.menu && projectView.popupMenu.created)
1596 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, 0); if(menu) menu.disabled = unavailable;
1597 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, 0); if(menu) menu.disabled = unavailable;
1598 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, 0); if(menu) menu.disabled = unavailable;
1599 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0); if(menu) menu.disabled = unavailable;
1600 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0); if(menu) menu.disabled = unavailable;
1601 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0); if(menu) menu.disabled = unavailable;
1602 projectView.popupMenu.Update(null);
1606 void AdjustDebugMenus()
1608 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1609 projectView.buildInProgress == buildingMainProject;
1610 bool active = ide.debugger.isActive;
1611 bool executing = ide.debugger.state == running;
1612 //bool holding = ide.debugger.state == stopped;
1614 debugStartResumeItem.disabled = unavailable || executing;
1615 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1616 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1619 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1620 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1623 debugBreakItem.disabled = unavailable || !executing;
1624 debugStopItem.disabled = unavailable || !active;
1625 debugRestartItem.disabled = unavailable || !active;
1628 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1629 toolBar.buttonDebugStop.disabled = unavailable || !active;
1630 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1633 debugStepIntoItem.disabled = unavailable || executing;
1634 debugStepOverItem.disabled = unavailable || executing;
1635 debugStepOutItem.disabled = unavailable || executing || !active;
1636 debugSkipStepOverItem.disabled = unavailable || executing;
1637 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1640 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1641 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1642 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1643 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1644 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1646 if((Designer)GetActiveDesigner())
1648 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1651 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1652 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1657 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1659 char tempString[MAX_LOCATION];
1660 strcpy(tempString, directory);
1661 if(saveSettings && !projectView)
1663 ideSettings.ideFileDialogLocation = directory;
1664 settingsContainer.Save();
1667 ideFileDialog.currentDirectory = tempString;
1668 codeEditorFileDialog.currentDirectory = tempString;
1669 codeEditorFormFileDialog.currentDirectory = tempString;
1672 void ChangeProjectFileDialogDirectory(char * directory)
1674 ideSettings.ideProjectFileDialogLocation = directory;
1675 settingsContainer.Save();
1678 Window FindWindow(char * filePath)
1680 Window document = null;
1682 // TOCHECK: Do we need to change slashes here?
1683 for(document = firstChild; document; document = document.next)
1685 char * fileName = document.fileName;
1686 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1688 document.visible = true;
1689 document.Activate();
1696 bool DontTerminateDebugSession(char * title)
1698 if(debugger.isActive)
1700 if(MessageBox { type = yesNo, master = ide,
1701 contents = $"Do you want to terminate the debugging session in progress?",
1702 text = title }.Modal() == no)
1705 MessageBox msg { type = yesNo, master = ide,
1706 contents = "Do you want to terminate the debugging session in progress?",
1708 if(msg.Modal() == no)
1720 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1722 char extension[MAX_EXTENSION] = "";
1723 Window document = null;
1724 bool isProject = false;
1725 bool needFileModified = true;
1726 char winFilePath[MAX_LOCATION];
1727 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1731 GetExtension(filePath, extension);
1735 strcpy(extension, type);
1737 if(strcmp(extension, ProjectExtension))
1739 for(document = firstChild; document; document = document.next)
1741 char * fileName = document.fileName;
1742 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1744 document.visible = true;
1746 document.Activate();
1752 if(createIfFails == whatever)
1754 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1756 if(openMethod == normal)
1758 if(DontTerminateDebugSession($"Open Project"))
1761 if(MenuWindowCloseAll(null, 0))
1765 projectView.visible = false;
1766 projectView.Destroy(0);
1767 // Where did this come from? projectView = null;
1774 Workspace workspace = null;
1776 if(FileExists(filePath))
1778 if(!strcmp(extension, ProjectExtension))
1780 char workspaceFile[MAX_LOCATION];
1781 strcpy(workspaceFile, filePath);
1782 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1783 workspace = LoadWorkspace(workspaceFile, filePath);
1785 else if(!strcmp(extension, WorkspaceExtension))
1786 workspace = LoadWorkspace(filePath, null);
1789 //project = LoadProject(filePath);
1794 char absolutePath[MAX_LOCATION];
1795 CreateProjectView(workspace, filePath);
1796 document = projectView;
1798 workspace.DropInvalidBreakpoints();
1801 ide.projectView.ShowOutputBuildLog(true);
1803 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1804 ide.projectView.DisplayCompiler(compiler, false);
1809 char newWorkingDir[MAX_LOCATION];
1810 StripLastDirectory(filePath, newWorkingDir);
1811 ChangeFileDialogsDirectory(newWorkingDir, false);
1814 document.fileName = filePath;
1816 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1818 // this crashes on starting ide with epj file, solution please?
1819 // app.UpdateDisplay();
1821 workspace.holdTracking = true;
1822 for(ofi : workspace.openedFiles)
1824 if(ofi.state != closed)
1826 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1829 char fileName[MAX_LOCATION];
1831 GetLastDirectory(ofi.path, fileName);
1832 node = projectView.project.topNode.Find(fileName, true);
1834 node.EnsureVisible();
1838 workspace.holdTracking = false;
1840 workspace.timer.Start();
1842 findInFilesDialog.mode = FindInFilesMode::project;
1843 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1846 char location[MAX_LOCATION];
1847 StripLastDirectory(ide.project.topNode.path, location);
1848 ChangeProjectFileDialogDirectory(location);
1852 if(projectView.debugger)
1853 projectView.debugger.EvaluateWatches();
1860 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1862 ideProjectFileDialog.text = openProjectFileDialogTitle;
1863 if(ideProjectFileDialog.Modal() == cancel)
1865 filePath = ideProjectFileDialog.filePath;
1866 GetExtension(filePath, extension);
1877 else if(openMethod == add)
1882 char slashFilePath[MAX_LOCATION];
1883 GetSlashPathBuffer(slashFilePath, filePath);
1884 for(p : workspace.projects)
1886 if(!fstrcmp(p.filePath, slashFilePath))
1894 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1895 contents = $"This project is already present in workspace." }.Modal();
1899 prj = LoadProject(filePath);
1902 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1903 workspace.projects.Add(prj);
1905 projectView.AddNode(prj.topNode, null);
1906 workspace.modified = true;
1908 findInFilesDialog.AddProjectItem(prj);
1909 projectView.ShowOutputBuildLog(true);
1910 projectView.DisplayCompiler(compiler, false);
1911 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1915 char location[MAX_LOCATION];
1916 StripLastDirectory(prj.topNode.path, location);
1917 ChangeProjectFileDialogDirectory(location);
1920 // projectView is associated with the main project and not with the one just added but
1921 return projectView; // just to let the caller know something was opened
1929 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1930 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1931 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1933 if(FileExists(filePath))
1934 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1935 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1936 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1939 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1942 else if(!strcmp(extension, "3ds"))
1944 if(FileExists(filePath))
1945 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1946 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1947 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1951 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1954 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1955 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1956 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1957 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1958 !strcmp(extension, "js"))
1960 CodeEditor editor { parent = this, state = state, visible = false };
1961 editor.updatingCode = true;
1962 if(editor.LoadFile(filePath))
1965 editor.visible = true;
1969 needFileModified = false;
1973 CodeEditor editor { parent = this, state = state, visible = false };
1974 if(editor.LoadFile(filePath))
1977 editor.visible = true;
1981 needFileModified = false;
1984 if(document && (document._class == class(PictureEdit) ||
1985 document._class == class(ModelView)))
1990 document.fileName = filePath;
1991 if(workspace && !workspace.holdTracking)
1992 workspace.UpdateOpenedFileInfo(filePath, opened);
1996 if(!document && createIfFails != no)
1998 if(createIfFails != yes && !needFileModified &&
1999 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
2000 createIfFails = yes;
2001 if(createIfFails == yes || createIfFails == whatever)
2003 document = (Window)NewCodeEditor(this, state, true);
2005 document.fileName = filePath;
2011 if(projectView && document._class == class(CodeEditor) && workspace)
2013 int lineNumber, position;
2015 CodeEditor editor = (CodeEditor)document;
2016 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2017 editor.openedFileInfo.holdTracking = true;
2018 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2019 position = Max(editor.openedFileInfo.position - 1, 0);
2020 editor.editBox.GoToLineNum(lineNumber);
2021 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2022 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2023 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2024 editor.editBox.scroll = scroll;
2025 editor.openedFileInfo.holdTracking = false;
2028 if(needFileModified)
2029 document.OnFileModified = OnFileModified;
2030 document.NotifySaved = DocumentSaved;
2033 ideSettings.AddRecentProject(document.fileName);
2035 ideSettings.AddRecentFile(document.fileName);
2036 ide.UpdateRecentMenus();
2037 settingsContainer.Save();
2045 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2046 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2048 if(!parentClosing && ide.workspace)
2049 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2052 bool ModelView::ModelViewOnClose(bool parentClosing)
2054 if(!parentClosing && ide.workspace)
2055 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2058 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2060 if(!parentClosing && ide.workspace)
2061 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2066 void OnUnloadGraphics(Window window)
2068 display.ClearMaterials();
2069 display.ClearTextures();
2070 display.ClearMeshes();
2074 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2076 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2077 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2081 bool OnKeyDown(Key key, unichar ch)
2086 projectView.Update(null);
2089 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2092 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2098 void GoToError(const char * line)
2101 projectView.GoToError(line);
2104 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2107 char *colon = strchr(text, ':');
2108 char filePath[MAX_LOCATION];
2109 char completePath[MAX_LOCATION];
2110 int line = 0, col = 0;
2115 char * close = strchr(text, ')');
2119 strncpy(name, &text[4], close - text - 4);
2120 name[close - text - 4] = '\0';
2121 for(p : ide.workspace.projects)
2123 if(!strcmp(p.name, name))
2133 prj = project ? project : (dir ? null : ide.project);
2134 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2136 path = (colon - 1 > path) ? colon - 1 : path;
2137 colon = strstr(colon + 1, ":");
2139 while(isspace(*path)) path++;
2142 strncpy(filePath, path, colon - path);
2143 filePath[colon - path] = '\0';
2144 line = atoi(colon + 1);
2145 colon = strstr(colon + 1, ":");
2147 col = atoi(colon + 1);
2149 else if(path - 1 >= path && *(path - 1) == '\"')
2151 colon = strchr(path, '\"');
2154 strncpy(filePath, path, colon - path);
2155 filePath[colon - path] = '\0';
2160 strcpy(completePath, prj.topNode.path);
2161 else if(dir && dir[0])
2162 strcpy(completePath, dir);
2164 completePath[0] = '\0';
2165 PathCat(completePath, filePath);
2167 if(FileExists(completePath).isFile)
2169 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2170 if(codeEditor && line)
2172 EditBox editBox = codeEditor.editBox;
2173 editBox.GoToLineNum(line - 1);
2174 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2179 void OnRedraw(Surface surface)
2181 Bitmap bitmap = back.bitmap;
2183 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2186 void SheetSelected(SheetType sheetSelected)
2188 if(activeChild == sheet)
2190 if(sheetSelected == methods)
2192 viewPropertiesItem.accelerator = f4;
2193 viewPropertiesItem.parent = viewMenu;
2194 viewMethodsItem.parent = null;
2198 viewMethodsItem.accelerator = f4;
2199 viewMethodsItem.parent = viewMenu;
2200 viewPropertiesItem.parent = null;
2205 viewMethodsItem.parent = viewMenu;
2206 viewPropertiesItem.parent = viewMenu;
2207 if(sheetSelected == methods)
2209 viewMethodsItem.accelerator = f4;
2210 viewPropertiesItem.accelerator = 0;
2214 viewMethodsItem.accelerator = 0;
2215 viewPropertiesItem.accelerator = f4;
2220 void OnActivateClient(Window client, Window previous)
2222 //if(!client || client != previous)
2225 if(!client || client != previous)
2228 dataType = previous._class;
2229 if(previous && !strcmp(dataType.name, "CodeEditor"))
2231 ((CodeEditor)previous).UpdateFormCode();
2233 else if(previous && !strcmp(dataType.name, "Designer"))
2235 ((Designer)previous).codeEditor.UpdateFormCode();
2240 dataType = client._class;
2241 if(client && !strcmp(dataType.name, "CodeEditor"))
2243 CodeEditor codeEditor = (CodeEditor)client;
2244 SetPrivateModule(codeEditor.privateModule);
2245 SetCurrentContext(codeEditor.globalContext);
2246 SetTopContext(codeEditor.globalContext);
2247 SetGlobalContext(codeEditor.globalContext);
2249 SetDefines(&codeEditor.defines);
2250 SetImports(&codeEditor.imports);
2252 SetActiveDesigner(codeEditor.designer);
2254 sheet.codeEditor = codeEditor;
2255 toolBox.codeEditor = codeEditor;
2257 viewDesignerItem.parent = viewMenu;
2258 if(activeChild != codeEditor)
2260 viewCodeItem.parent = viewMenu;
2261 viewDesignerItem.accelerator = 0;
2262 viewCodeItem.accelerator = f8;
2266 viewCodeItem.parent = null;
2267 viewDesignerItem.accelerator = f8;
2270 else if(client && !strcmp(dataType.name, "Designer"))
2272 CodeEditor codeEditor = ((Designer)client).codeEditor;
2275 SetPrivateModule(codeEditor.privateModule);
2276 SetCurrentContext(codeEditor.globalContext);
2277 SetTopContext(codeEditor.globalContext);
2278 SetGlobalContext(codeEditor.globalContext);
2279 SetDefines(&codeEditor.defines);
2280 SetImports(&codeEditor.imports);
2284 SetPrivateModule(null);
2285 SetCurrentContext(null);
2286 SetTopContext(null);
2287 SetGlobalContext(null);
2292 SetActiveDesigner((Designer)client);
2294 sheet.codeEditor = codeEditor;
2295 toolBox.codeEditor = codeEditor;
2297 viewCodeItem.parent = viewMenu;
2298 if(activeChild != client)
2300 viewDesignerItem.parent = viewMenu;
2301 viewDesignerItem.accelerator = f8;
2302 viewCodeItem.accelerator = 0;
2306 viewDesignerItem.parent = null;
2307 viewCodeItem.accelerator = f8;
2313 sheet.codeEditor = null;
2314 toolBox.codeEditor = null;
2315 SetActiveDesigner(null);
2317 viewDesignerItem.parent = null;
2318 viewCodeItem.parent = null;
2321 SheetSelected(sheet.sheetSelected);
2324 projectCompileItem = null;
2329 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2331 CodeEditor codeEditor = (CodeEditor)client;
2332 EditBox editBox = codeEditor.editBox;
2334 statusBar.AddField(pos);
2336 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2337 statusBar.AddField(caps);
2339 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2340 statusBar.AddField(ovr);
2342 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2343 statusBar.AddField(num);
2345 //statusBar.text = "Ready";
2347 if(projectView && projectView.project)
2349 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2353 sprintf(name, $"Compile %s", node.name);
2354 projectCompileItem =
2356 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2358 bool NotifySelect(MenuItem selection, Modifiers mods)
2362 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2364 projectView.Compile(node);
2369 projectMenu.AddDynamic(projectCompileItem, ide, false);
2375 caps = ovr = num = null;
2380 bool OnClose(bool parentClosing)
2382 //return !projectView.buildInProgress;
2383 if(projectView && projectView.buildInProgress)
2385 if(DontTerminateDebugSession($"Close IDE"))
2387 if(findInFilesDialog)
2388 findInFilesDialog.SearchStop();
2391 workspace.timer.Stop();
2394 ideMainFrame.Destroy(0);
2401 for(c = 1; c<app.argc; c++)
2403 char fullPath[MAX_LOCATION];
2404 char parentPath[MAX_LOCATION];
2405 char ext[MAX_EXTENSION];
2407 FileAttribs dirAttribs;
2408 GetWorkingDir(fullPath, MAX_LOCATION);
2409 PathCat(fullPath, app.argv[c]);
2410 StripLastDirectory(fullPath, parentPath);
2411 GetExtension(app.argv[c], ext);
2412 isProject = !strcmpi(ext, "epj");
2414 if(isProject && c > 1) continue;
2416 // Create directory for projects (only)
2417 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2419 if(isProject && !FileExists(fullPath))
2421 // The NewProject will handle directory creation
2422 /*if(!dirAttribs.isDirectory)
2424 MakeDir(parentPath);
2425 dirAttribs = FileExists(parentPath);
2427 if(dirAttribs.isDirectory)*/
2429 char name[MAX_LOCATION];
2430 NewProjectDialog newProjectDialog;
2434 projectView.visible = false;
2435 if(!projectView.Destroy(0))
2439 newProjectDialog = { master = this };
2441 strcpy(name, app.argv[c]);
2442 StripExtension(name);
2443 GetLastDirectory(name, name);
2444 newProjectDialog.projectName.contents = name;
2445 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2446 newProjectDialog.locationEditBox.path = parentPath;
2447 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2449 newProjectDialog.Modal();
2452 ideSettings.AddRecentProject(projectView.fileName);
2453 ide.UpdateRecentMenus();
2454 settingsContainer.Save();
2457 // Open only one project
2461 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2469 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2472 projectView.visible = false;
2473 projectView.Destroy(0);
2476 #ifdef GDB_DEBUG_GUI
2477 gdbDialog.Destroy(0);
2482 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2486 char * oldPaths[128];
2487 String oldList = new char[maxPathLen];
2488 Array<String> newExePaths { };
2489 //Map<String, bool> exePathExists { };
2491 #if defined(__unix__) || defined(__APPLE__)
2492 Array<String> newLibPaths { };
2493 Map<String, bool> libPathExists { };
2498 for(prj : workspace.projects)
2500 DirExpression targetDirExp;
2502 // SKIP FIRST PROJECT...
2503 if(prj == workspace.projects.firstIterator.data) continue;
2505 // NOTE: Right now the additional project config dir will be
2506 // obtained when the debugger is started, so toggling it
2507 // while building will change which library gets used.
2508 // To go with the initial state, e.g. when F5 was pressed,
2509 // we nould need to keep a list of all project's active
2510 // config upon startup.
2511 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2513 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2517 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2518 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2522 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2523 if(cfg.targetType == sharedLibrary && cfg.debug)
2527 if(targetDirExp.dir)
2529 char buffer[MAX_LOCATION];
2530 #if defined(__WIN32__)
2531 Array<String> paths = newExePaths;
2533 Array<String> paths = newLibPaths;
2535 GetSystemPathBuffer(buffer, prj.topNode.path);
2536 PathCat(buffer, targetDirExp.dir);
2539 if(!fstrcmp(p, buffer))
2546 paths.Add(CopyString(buffer));
2548 delete targetDirExp;
2552 for(item : compiler.executableDirs)
2555 for(p : newExePaths)
2557 if(!fstrcmp(p, item))
2564 newExePaths.Add(CopySystemPath(item));
2567 GetEnvironment("PATH", oldList, maxPathLen);
2569 printf("Old value of PATH: %s\n", oldList);
2571 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2572 for(c = 0; c < count; c++)
2575 for(p : newExePaths)
2577 if(!fstrcmp(p, oldPaths[c]))
2584 newExePaths.Add(CopySystemPath(oldPaths[c]));
2588 for(path : newExePaths)
2589 len += strlen(path) + 1;
2590 newList = new char[len + 1];
2592 for(path : newExePaths)
2594 strcat(newList, path);
2595 strcat(newList, pathListSep);
2597 newList[len - 1] = '\0';
2598 SetEnvironment("PATH", newList);
2600 printf("New value of PATH: %s\n", newList);
2607 #if defined(__unix__) || defined(__APPLE__)
2609 for(item : compiler.libraryDirs)
2611 if(!libPathExists[item]) // fstrcmp should be used
2613 newLibPaths.Add(item);
2614 libPathExists[item] = true;
2618 #if defined(__APPLE__)
2619 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2621 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2624 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2626 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2627 for(c = 0; c < count; c++)
2629 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2631 newLibPaths.Add(oldPaths[c]);
2632 libPathExists[oldPaths[c]] = true;
2637 for(path : newLibPaths)
2638 len += strlen(path) + 1;
2639 newList = new char[len + 1];
2641 for(path : newLibPaths)
2643 strcat(newList, path);
2644 strcat(newList, pathListSep);
2646 newList[len - 1] = '\0';
2647 #if defined(__APPLE__)
2648 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2650 SetEnvironment("LD_LIBRARY_PATH", newList);
2653 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2658 delete libPathExists;
2661 if(compiler.distccEnabled && compiler.distccHosts)
2662 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2667 void DestroyTemporaryProjectDir()
2669 if(tmpPrjDir && tmpPrjDir[0])
2671 if(FileExists(tmpPrjDir).isDirectory)
2672 DestroyDir(tmpPrjDir);
2673 property::tmpPrjDir = null;
2679 // Graphics Driver Menu
2683 app.currentSkin.selectionColor = selectionColor;
2684 app.currentSkin.selectionText = selectionText;
2688 driverItems = new MenuItem[app.numDrivers];
2689 for(c = 0; c < app.numDrivers; c++)
2691 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2692 driverItems[c].id = c;
2693 driverItems[c].isRadio = true;
2696 driverItems = new MenuItem[2];
2697 #if defined(__unix__)
2698 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2699 driverItems[0].id = 0;
2700 driverItems[0].isRadio = true;
2702 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2703 driverItems[0].id = 0;
2704 driverItems[0].isRadio = true;
2706 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2707 driverItems[1].id = 1;
2708 driverItems[1].isRadio = true;
2710 /* skinItems = new MenuItem[app.numSkins];
2711 for(c = 0; c < app.numSkins; c++)
2713 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2714 skinItems[c].id = c;
2715 skinItems[c].isRadio = true;
2718 ideFileDialog.master = this;
2719 ideProjectFileDialog.master = this;
2721 //SetDriverAndSkin();
2725 void UpdateRecentMenus()
2728 Menu fileMenu = menu.FindMenu($"File");
2729 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2730 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2731 char itemName[MAX_LOCATION + 4];
2734 recentFiles.Clear();
2737 for(recent : ideSettings.recentFiles)
2739 sprintf(itemName, "%d %s", 1 + c, recent);
2740 MakeSystemPath(itemName);
2741 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2745 recentProjects.Clear();
2747 for(recent : ideSettings.recentProjects)
2749 sprintf(itemName, "%d %s", 1 + c, recent);
2750 MakeSystemPath(itemName);
2751 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2764 void DestroyDir(char * path)
2766 RecursiveDeleteFolderFSI fsi { };
2771 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2773 bool preserveRootFolder;
2775 void OutFolder(char * folderPath, bool isRoot)
2777 if(!(preserveRootFolder && isRoot))
2778 RemoveDir(folderPath);
2781 bool OnFile(char * filePath)
2783 DeleteFile(filePath);
2788 class IDEApp : GuiApplication
2790 //driver = "Win32Console";
2791 // driver = "OpenGL";
2796 SetLoggingMode(stdOut, null);
2797 //SetLoggingMode(debug, null);
2799 settingsContainer.Load();
2800 #if defined(__unix__) || defined(__APPLE__)
2801 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2803 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2805 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2809 desktop.text = titleECEREIDE;
2812 for(c = 1; c<app.argc; c++)
2814 char fullPath[MAX_LOCATION];
2815 GetWorkingDir(fullPath, MAX_LOCATION);
2816 PathCat(fullPath, app.argv[c]);
2817 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2824 IDEMainFrame ideMainFrame { };
2826 define app = ((IDEApp)__thisModule);
2828 define titleECEREIDE = $"ECERE IDE (Debug)";
2830 define titleECEREIDE = $"ECERE IDE";