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, disabled = true;
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 ide.AdjustFileMenus();
1499 settingsContainer.Save();
1502 bool Window::OnFileModified(FileChange fileChange, char * param)
1505 sprintf(temp, $"The document %s was modified by another application.\n"
1506 "Would you like to reload it and lose your changes?", this.fileName);
1507 if(MessageBox { type = yesNo, master = this/*.parent*/,
1508 text = $"Document has been modified", contents = temp }.Modal() == yes)
1510 char * fileName = CopyString(this.fileName);
1511 WindowState state = this.state;
1512 Anchor anchor = this.anchor;
1513 Size size = this.size;
1515 this.modifiedDocument = false;
1517 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1520 this.anchor = anchor;
1522 this.SetState(state, true, 0);
1530 void UpdateMakefiles()
1534 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1535 projectView.ShowOutputBuildLog(true);
1536 projectView.DisplayCompiler(compiler, false);
1537 for(prj : workspace.projects)
1538 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1545 bool unavailable = !project;
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;
1563 property bool hasOpenedCodeEditors
1568 for(w = firstChild; w; w = w.next)
1569 if(w._class == class(CodeEditor) &&
1570 w.isDocument && !w.closing && w.visible && w.created &&
1571 w.fileName && w.fileName[0])
1577 void AdjustFileMenus()
1579 bool unavailable = project != null || !hasOpenedCodeEditors; // are they supported source code (ec, c, cpp, etc) ?
1581 projectQuickItem.disabled = unavailable;
1584 void AdjustBuildMenus()
1586 bool unavailable = project && projectView.buildInProgress;
1588 projectNewItem.disabled = unavailable;
1589 toolBar.buttonNewProject.disabled = unavailable;
1590 projectOpenItem.disabled = unavailable;
1591 toolBar.buttonOpenProject.disabled = unavailable;
1593 unavailable = !project || projectView.buildInProgress;
1595 projectCloseItem.disabled = unavailable;
1596 // toolBar.buttonCloseProject.disabled = unavailable;
1598 projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
1599 toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
1600 projectBuildItem.disabled = unavailable;
1601 toolBar.buttonBuild.disabled = unavailable;
1602 projectLinkItem.disabled = unavailable;
1603 toolBar.buttonReLink.disabled = unavailable;
1604 projectRebuildItem.disabled = unavailable;
1605 toolBar.buttonRebuild.disabled = unavailable;
1606 projectCleanItem.disabled = unavailable;
1607 toolBar.buttonClean.disabled = unavailable;
1608 projectRealCleanItem.disabled = unavailable;
1609 // toolBar.buttonRealClean.disabled = unavailable;
1610 projectRegenerateItem.disabled = unavailable;
1611 toolBar.buttonRegenerateMakefile.disabled = unavailable;
1612 projectCompileItem.disabled = unavailable;
1614 if(projectView && projectView.popupMenu && projectView.popupMenu.menu && projectView.popupMenu.created)
1617 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, 0); if(menu) menu.disabled = unavailable;
1618 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, 0); if(menu) menu.disabled = unavailable;
1619 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, 0); if(menu) menu.disabled = unavailable;
1620 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0); if(menu) menu.disabled = unavailable;
1621 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0); if(menu) menu.disabled = unavailable;
1622 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0); if(menu) menu.disabled = unavailable;
1623 projectView.popupMenu.Update(null);
1627 void AdjustDebugMenus()
1629 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1630 projectView.buildInProgress == buildingMainProject;
1631 bool active = ide.debugger.isActive;
1632 bool executing = ide.debugger.state == running;
1633 //bool holding = ide.debugger.state == stopped;
1635 debugStartResumeItem.disabled = unavailable || executing;
1636 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1637 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1640 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1641 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1644 debugBreakItem.disabled = unavailable || !executing;
1645 debugStopItem.disabled = unavailable || !active;
1646 debugRestartItem.disabled = unavailable || !active;
1649 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1650 toolBar.buttonDebugStop.disabled = unavailable || !active;
1651 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1654 debugStepIntoItem.disabled = unavailable || executing;
1655 debugStepOverItem.disabled = unavailable || executing;
1656 debugStepOutItem.disabled = unavailable || executing || !active;
1657 debugSkipStepOverItem.disabled = unavailable || executing;
1658 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1661 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1662 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1663 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1664 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1665 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1667 if((Designer)GetActiveDesigner())
1669 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1672 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1673 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1678 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1680 char tempString[MAX_LOCATION];
1681 strcpy(tempString, directory);
1682 if(saveSettings && !projectView)
1684 ideSettings.ideFileDialogLocation = directory;
1685 settingsContainer.Save();
1688 ideFileDialog.currentDirectory = tempString;
1689 codeEditorFileDialog.currentDirectory = tempString;
1690 codeEditorFormFileDialog.currentDirectory = tempString;
1693 void ChangeProjectFileDialogDirectory(char * directory)
1695 ideSettings.ideProjectFileDialogLocation = directory;
1696 settingsContainer.Save();
1699 Window FindWindow(char * filePath)
1701 Window document = null;
1703 // TOCHECK: Do we need to change slashes here?
1704 for(document = firstChild; document; document = document.next)
1706 char * fileName = document.fileName;
1707 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1709 document.visible = true;
1710 document.Activate();
1717 bool DontTerminateDebugSession(char * title)
1719 if(debugger.isActive)
1721 if(MessageBox { type = yesNo, master = ide,
1722 contents = $"Do you want to terminate the debugging session in progress?",
1723 text = title }.Modal() == no)
1726 MessageBox msg { type = yesNo, master = ide,
1727 contents = "Do you want to terminate the debugging session in progress?",
1729 if(msg.Modal() == no)
1741 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1743 char extension[MAX_EXTENSION] = "";
1744 Window document = null;
1745 bool isProject = false;
1746 bool needFileModified = true;
1747 char winFilePath[MAX_LOCATION];
1748 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1752 GetExtension(filePath, extension);
1756 strcpy(extension, type);
1758 if(strcmp(extension, ProjectExtension))
1760 for(document = firstChild; document; document = document.next)
1762 char * fileName = document.fileName;
1763 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1765 document.visible = true;
1767 document.Activate();
1773 if(createIfFails == whatever)
1775 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1777 needFileModified = false;
1778 if(openMethod == normal)
1780 if(DontTerminateDebugSession($"Open Project"))
1783 if(MenuWindowCloseAll(null, 0))
1787 projectView.visible = false;
1788 projectView.Destroy(0);
1789 // Where did this come from? projectView = null;
1796 Workspace workspace = null;
1798 if(FileExists(filePath))
1800 if(!strcmp(extension, ProjectExtension))
1802 char workspaceFile[MAX_LOCATION];
1803 strcpy(workspaceFile, filePath);
1804 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1805 workspace = LoadWorkspace(workspaceFile, filePath);
1807 else if(!strcmp(extension, WorkspaceExtension))
1808 workspace = LoadWorkspace(filePath, null);
1811 //project = LoadProject(filePath);
1816 char absolutePath[MAX_LOCATION];
1817 CreateProjectView(workspace, filePath);
1818 document = projectView;
1820 workspace.DropInvalidBreakpoints();
1823 ide.projectView.ShowOutputBuildLog(true);
1825 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1826 ide.projectView.DisplayCompiler(compiler, false);
1831 char newWorkingDir[MAX_LOCATION];
1832 StripLastDirectory(filePath, newWorkingDir);
1833 ChangeFileDialogsDirectory(newWorkingDir, false);
1836 document.fileName = filePath;
1838 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1840 // this crashes on starting ide with epj file, solution please?
1841 // app.UpdateDisplay();
1843 workspace.holdTracking = true;
1844 for(ofi : workspace.openedFiles)
1846 if(ofi.state != closed)
1848 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1851 char fileName[MAX_LOCATION];
1853 GetLastDirectory(ofi.path, fileName);
1854 node = projectView.project.topNode.Find(fileName, true);
1856 node.EnsureVisible();
1860 workspace.holdTracking = false;
1862 workspace.timer.Start();
1864 findInFilesDialog.mode = FindInFilesMode::project;
1865 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1868 char location[MAX_LOCATION];
1869 StripLastDirectory(ide.project.topNode.path, location);
1870 ChangeProjectFileDialogDirectory(location);
1874 if(projectView.debugger)
1875 projectView.debugger.EvaluateWatches();
1882 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1884 ideProjectFileDialog.text = openProjectFileDialogTitle;
1885 if(ideProjectFileDialog.Modal() == cancel)
1887 filePath = ideProjectFileDialog.filePath;
1888 GetExtension(filePath, extension);
1899 else if(openMethod == add)
1904 char slashFilePath[MAX_LOCATION];
1905 GetSlashPathBuffer(slashFilePath, filePath);
1906 for(p : workspace.projects)
1908 if(!fstrcmp(p.filePath, slashFilePath))
1916 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1917 contents = $"This project is already present in workspace." }.Modal();
1921 prj = LoadProject(filePath);
1924 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1925 prj.StartMonitoring();
1926 workspace.projects.Add(prj);
1928 projectView.AddNode(prj.topNode, null);
1929 workspace.modified = true;
1931 findInFilesDialog.AddProjectItem(prj);
1932 projectView.ShowOutputBuildLog(true);
1933 projectView.DisplayCompiler(compiler, false);
1934 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1938 char location[MAX_LOCATION];
1939 StripLastDirectory(prj.topNode.path, location);
1940 ChangeProjectFileDialogDirectory(location);
1943 // projectView is associated with the main project and not with the one just added but
1944 return projectView; // just to let the caller know something was opened
1952 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1953 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1954 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1956 if(FileExists(filePath))
1957 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1958 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1959 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1962 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1965 else if(!strcmp(extension, "3ds"))
1967 if(FileExists(filePath))
1968 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1969 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1970 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1974 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1977 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1978 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1979 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1980 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1981 !strcmp(extension, "js"))
1983 CodeEditor editor { parent = this, state = state, visible = false };
1984 editor.updatingCode = true;
1985 if(editor.LoadFile(filePath))
1988 editor.visible = true;
1992 needFileModified = false;
1996 CodeEditor editor { parent = this, state = state, visible = false };
1997 if(editor.LoadFile(filePath))
2000 editor.visible = true;
2004 needFileModified = false;
2007 if(document && (document._class == class(PictureEdit) ||
2008 document._class == class(ModelView)))
2013 document.fileName = filePath;
2014 if(workspace && !workspace.holdTracking)
2015 workspace.UpdateOpenedFileInfo(filePath, opened);
2019 if(!document && createIfFails != no)
2021 if(createIfFails != yes && !needFileModified &&
2022 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
2023 createIfFails = yes;
2024 if(createIfFails == yes || createIfFails == whatever)
2026 document = (Window)NewCodeEditor(this, state, true);
2028 document.fileName = filePath;
2034 if(projectView && document._class == class(CodeEditor) && workspace)
2036 int lineNumber, position;
2038 CodeEditor editor = (CodeEditor)document;
2039 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2040 editor.openedFileInfo.holdTracking = true;
2041 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2042 position = Max(editor.openedFileInfo.position - 1, 0);
2043 editor.editBox.GoToLineNum(lineNumber);
2044 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2045 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2046 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2047 editor.editBox.scroll = scroll;
2048 editor.openedFileInfo.holdTracking = false;
2051 if(needFileModified)
2052 document.OnFileModified = OnFileModified;
2053 document.NotifySaved = DocumentSaved;
2056 ideSettings.AddRecentProject(document.fileName);
2058 ideSettings.AddRecentFile(document.fileName);
2059 ide.UpdateRecentMenus();
2060 ide.AdjustFileMenus();
2061 settingsContainer.Save();
2069 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2070 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2072 if(!parentClosing && ide.workspace)
2073 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2076 bool ModelView::ModelViewOnClose(bool parentClosing)
2078 if(!parentClosing && ide.workspace)
2079 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2082 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2084 if(!parentClosing && ide.workspace)
2085 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2090 void OnUnloadGraphics(Window window)
2092 display.ClearMaterials();
2093 display.ClearTextures();
2094 display.ClearMeshes();
2098 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2100 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2101 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2105 bool OnKeyDown(Key key, unichar ch)
2110 projectView.Update(null);
2113 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2116 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2122 void GoToError(const char * line)
2125 projectView.GoToError(line);
2128 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2131 char *colon = strchr(text, ':');
2132 char filePath[MAX_LOCATION];
2133 char completePath[MAX_LOCATION];
2134 int line = 0, col = 0;
2139 char * close = strchr(text, ')');
2143 strncpy(name, &text[4], close - text - 4);
2144 name[close - text - 4] = '\0';
2145 for(p : ide.workspace.projects)
2147 if(!strcmp(p.name, name))
2157 prj = project ? project : (dir ? null : ide.project);
2158 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2160 path = (colon - 1 > path) ? colon - 1 : path;
2161 colon = strstr(colon + 1, ":");
2163 while(isspace(*path)) path++;
2166 strncpy(filePath, path, colon - path);
2167 filePath[colon - path] = '\0';
2168 line = atoi(colon + 1);
2169 colon = strstr(colon + 1, ":");
2171 col = atoi(colon + 1);
2173 else if(path - 1 >= path && *(path - 1) == '\"')
2175 colon = strchr(path, '\"');
2178 strncpy(filePath, path, colon - path);
2179 filePath[colon - path] = '\0';
2184 strcpy(completePath, prj.topNode.path);
2185 else if(dir && dir[0])
2186 strcpy(completePath, dir);
2188 completePath[0] = '\0';
2189 PathCat(completePath, filePath);
2191 if(FileExists(completePath).isFile)
2193 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2194 if(codeEditor && line)
2196 EditBox editBox = codeEditor.editBox;
2197 editBox.GoToLineNum(line - 1);
2198 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2203 void OnRedraw(Surface surface)
2205 Bitmap bitmap = back.bitmap;
2207 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2210 void SheetSelected(SheetType sheetSelected)
2212 if(activeChild == sheet)
2214 if(sheetSelected == methods)
2216 viewPropertiesItem.accelerator = f4;
2217 viewPropertiesItem.parent = viewMenu;
2218 viewMethodsItem.parent = null;
2222 viewMethodsItem.accelerator = f4;
2223 viewMethodsItem.parent = viewMenu;
2224 viewPropertiesItem.parent = null;
2229 viewMethodsItem.parent = viewMenu;
2230 viewPropertiesItem.parent = viewMenu;
2231 if(sheetSelected == methods)
2233 viewMethodsItem.accelerator = f4;
2234 viewPropertiesItem.accelerator = 0;
2238 viewMethodsItem.accelerator = 0;
2239 viewPropertiesItem.accelerator = f4;
2244 void OnActivateClient(Window client, Window previous)
2246 //if(!client || client != previous)
2249 if(!client || client != previous)
2252 dataType = previous._class;
2253 if(previous && !strcmp(dataType.name, "CodeEditor"))
2255 ((CodeEditor)previous).UpdateFormCode();
2257 else if(previous && !strcmp(dataType.name, "Designer"))
2259 ((Designer)previous).codeEditor.UpdateFormCode();
2264 dataType = client._class;
2265 if(client && !strcmp(dataType.name, "CodeEditor"))
2267 CodeEditor codeEditor = (CodeEditor)client;
2268 SetPrivateModule(codeEditor.privateModule);
2269 SetCurrentContext(codeEditor.globalContext);
2270 SetTopContext(codeEditor.globalContext);
2271 SetGlobalContext(codeEditor.globalContext);
2273 SetDefines(&codeEditor.defines);
2274 SetImports(&codeEditor.imports);
2276 SetActiveDesigner(codeEditor.designer);
2278 sheet.codeEditor = codeEditor;
2279 toolBox.codeEditor = codeEditor;
2281 viewDesignerItem.parent = viewMenu;
2282 if(activeChild != codeEditor)
2284 viewCodeItem.parent = viewMenu;
2285 viewDesignerItem.accelerator = 0;
2286 viewCodeItem.accelerator = f8;
2290 viewCodeItem.parent = null;
2291 viewDesignerItem.accelerator = f8;
2294 else if(client && !strcmp(dataType.name, "Designer"))
2296 CodeEditor codeEditor = ((Designer)client).codeEditor;
2299 SetPrivateModule(codeEditor.privateModule);
2300 SetCurrentContext(codeEditor.globalContext);
2301 SetTopContext(codeEditor.globalContext);
2302 SetGlobalContext(codeEditor.globalContext);
2303 SetDefines(&codeEditor.defines);
2304 SetImports(&codeEditor.imports);
2308 SetPrivateModule(null);
2309 SetCurrentContext(null);
2310 SetTopContext(null);
2311 SetGlobalContext(null);
2316 SetActiveDesigner((Designer)client);
2318 sheet.codeEditor = codeEditor;
2319 toolBox.codeEditor = codeEditor;
2321 viewCodeItem.parent = viewMenu;
2322 if(activeChild != client)
2324 viewDesignerItem.parent = viewMenu;
2325 viewDesignerItem.accelerator = f8;
2326 viewCodeItem.accelerator = 0;
2330 viewDesignerItem.parent = null;
2331 viewCodeItem.accelerator = f8;
2337 sheet.codeEditor = null;
2338 toolBox.codeEditor = null;
2339 SetActiveDesigner(null);
2341 viewDesignerItem.parent = null;
2342 viewCodeItem.parent = null;
2345 SheetSelected(sheet.sheetSelected);
2348 projectCompileItem = null;
2353 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2355 CodeEditor codeEditor = (CodeEditor)client;
2356 EditBox editBox = codeEditor.editBox;
2358 statusBar.AddField(pos);
2360 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2361 statusBar.AddField(caps);
2363 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2364 statusBar.AddField(ovr);
2366 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2367 statusBar.AddField(num);
2369 //statusBar.text = "Ready";
2371 if(projectView && projectView.project)
2373 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2377 sprintf(name, $"Compile %s", node.name);
2378 projectCompileItem =
2380 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2382 bool NotifySelect(MenuItem selection, Modifiers mods)
2386 bool result = false;
2387 ProjectNode node = null;
2388 for(p : ide.workspace.projects)
2390 node = projectView.GetNodeFromWindow(activeClient, p);
2391 if(node && projectView.Compile(node))
2398 ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name);
2403 projectMenu.AddDynamic(projectCompileItem, ide, false);
2409 caps = ovr = num = null;
2414 bool OnClose(bool parentClosing)
2416 //return !projectView.buildInProgress;
2417 if(projectView && projectView.buildInProgress)
2419 if(DontTerminateDebugSession($"Close IDE"))
2421 if(findInFilesDialog)
2422 findInFilesDialog.SearchStop();
2425 workspace.timer.Stop();
2428 ideMainFrame.Destroy(0);
2435 for(c = 1; c<app.argc; c++)
2437 char fullPath[MAX_LOCATION];
2438 char parentPath[MAX_LOCATION];
2439 char ext[MAX_EXTENSION];
2441 FileAttribs dirAttribs;
2442 GetWorkingDir(fullPath, MAX_LOCATION);
2443 PathCat(fullPath, app.argv[c]);
2444 StripLastDirectory(fullPath, parentPath);
2445 GetExtension(app.argv[c], ext);
2446 isProject = !strcmpi(ext, "epj");
2448 if(isProject && c > 1) continue;
2450 // Create directory for projects (only)
2451 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2453 if(isProject && !FileExists(fullPath))
2455 // The NewProject will handle directory creation
2456 /*if(!dirAttribs.isDirectory)
2458 MakeDir(parentPath);
2459 dirAttribs = FileExists(parentPath);
2461 if(dirAttribs.isDirectory)*/
2463 char name[MAX_LOCATION];
2464 NewProjectDialog newProjectDialog;
2468 projectView.visible = false;
2469 if(!projectView.Destroy(0))
2473 newProjectDialog = { master = this };
2475 strcpy(name, app.argv[c]);
2476 StripExtension(name);
2477 GetLastDirectory(name, name);
2478 newProjectDialog.projectName.contents = name;
2479 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2480 newProjectDialog.locationEditBox.path = parentPath;
2481 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2483 newProjectDialog.Modal();
2486 ideSettings.AddRecentProject(projectView.fileName);
2487 ide.UpdateRecentMenus();
2488 settingsContainer.Save();
2491 // Open only one project
2495 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2503 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2506 projectView.visible = false;
2507 projectView.Destroy(0);
2510 #ifdef GDB_DEBUG_GUI
2511 gdbDialog.Destroy(0);
2516 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2520 char * oldPaths[128];
2521 String oldList = new char[maxPathLen];
2522 Array<String> newExePaths { };
2523 //Map<String, bool> exePathExists { };
2525 #if defined(__unix__) || defined(__APPLE__)
2526 Array<String> newLibPaths { };
2527 Map<String, bool> libPathExists { };
2532 for(prj : workspace.projects)
2534 DirExpression targetDirExp;
2536 // SKIP FIRST PROJECT...
2537 if(prj == workspace.projects.firstIterator.data) continue;
2539 // NOTE: Right now the additional project config dir will be
2540 // obtained when the debugger is started, so toggling it
2541 // while building will change which library gets used.
2542 // To go with the initial state, e.g. when F5 was pressed,
2543 // we nould need to keep a list of all project's active
2544 // config upon startup.
2545 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2547 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2551 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2552 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2556 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2557 if(cfg.targetType == sharedLibrary && cfg.debug)
2561 if(targetDirExp.dir)
2563 char buffer[MAX_LOCATION];
2564 #if defined(__WIN32__)
2565 Array<String> paths = newExePaths;
2567 Array<String> paths = newLibPaths;
2569 GetSystemPathBuffer(buffer, prj.topNode.path);
2570 PathCat(buffer, targetDirExp.dir);
2573 if(!fstrcmp(p, buffer))
2580 paths.Add(CopyString(buffer));
2582 delete targetDirExp;
2586 for(item : compiler.executableDirs)
2589 for(p : newExePaths)
2591 if(!fstrcmp(p, item))
2598 newExePaths.Add(CopySystemPath(item));
2601 GetEnvironment("PATH", oldList, maxPathLen);
2603 printf("Old value of PATH: %s\n", oldList);
2605 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2606 for(c = 0; c < count; c++)
2609 for(p : newExePaths)
2611 if(!fstrcmp(p, oldPaths[c]))
2618 newExePaths.Add(CopySystemPath(oldPaths[c]));
2622 for(path : newExePaths)
2623 len += strlen(path) + 1;
2624 newList = new char[len + 1];
2626 for(path : newExePaths)
2628 strcat(newList, path);
2629 strcat(newList, pathListSep);
2631 newList[len - 1] = '\0';
2632 SetEnvironment("PATH", newList);
2634 printf("New value of PATH: %s\n", newList);
2641 #if defined(__unix__) || defined(__APPLE__)
2643 for(item : compiler.libraryDirs)
2645 if(!libPathExists[item]) // fstrcmp should be used
2647 newLibPaths.Add(item);
2648 libPathExists[item] = true;
2652 #if defined(__APPLE__)
2653 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2655 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2658 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2660 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2661 for(c = 0; c < count; c++)
2663 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2665 newLibPaths.Add(oldPaths[c]);
2666 libPathExists[oldPaths[c]] = true;
2671 for(path : newLibPaths)
2672 len += strlen(path) + 1;
2673 newList = new char[len + 1];
2675 for(path : newLibPaths)
2677 strcat(newList, path);
2678 strcat(newList, pathListSep);
2680 newList[len - 1] = '\0';
2681 #if defined(__APPLE__)
2682 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2684 SetEnvironment("LD_LIBRARY_PATH", newList);
2687 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2692 delete libPathExists;
2695 if(compiler.distccEnabled && compiler.distccHosts)
2696 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2701 void DestroyTemporaryProjectDir()
2703 if(tmpPrjDir && tmpPrjDir[0])
2705 if(FileExists(tmpPrjDir).isDirectory)
2706 DestroyDir(tmpPrjDir);
2707 property::tmpPrjDir = null;
2713 // Graphics Driver Menu
2717 app.currentSkin.selectionColor = selectionColor;
2718 app.currentSkin.selectionText = selectionText;
2722 driverItems = new MenuItem[app.numDrivers];
2723 for(c = 0; c < app.numDrivers; c++)
2725 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2726 driverItems[c].id = c;
2727 driverItems[c].isRadio = true;
2730 driverItems = new MenuItem[2];
2731 #if defined(__unix__)
2732 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2733 driverItems[0].id = 0;
2734 driverItems[0].isRadio = true;
2736 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2737 driverItems[0].id = 0;
2738 driverItems[0].isRadio = true;
2740 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2741 driverItems[1].id = 1;
2742 driverItems[1].isRadio = true;
2744 /* skinItems = new MenuItem[app.numSkins];
2745 for(c = 0; c < app.numSkins; c++)
2747 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2748 skinItems[c].id = c;
2749 skinItems[c].isRadio = true;
2752 ideFileDialog.master = this;
2753 ideProjectFileDialog.master = this;
2755 //SetDriverAndSkin();
2759 void UpdateRecentMenus()
2762 Menu fileMenu = menu.FindMenu($"File");
2763 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2764 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2765 char itemName[MAX_LOCATION + 4];
2768 recentFiles.Clear();
2771 for(recent : ideSettings.recentFiles)
2773 sprintf(itemName, "%d %s", 1 + c, recent);
2774 MakeSystemPath(itemName);
2775 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2779 recentProjects.Clear();
2781 for(recent : ideSettings.recentProjects)
2783 sprintf(itemName, "%d %s", 1 + c, recent);
2784 MakeSystemPath(itemName);
2785 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2798 void DestroyDir(char * path)
2800 RecursiveDeleteFolderFSI fsi { };
2805 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2807 bool preserveRootFolder;
2809 void OutFolder(char * folderPath, bool isRoot)
2811 if(!(preserveRootFolder && isRoot))
2812 RemoveDir(folderPath);
2815 bool OnFile(char * filePath)
2817 DeleteFile(filePath);
2822 class IDEApp : GuiApplication
2824 //driver = "Win32Console";
2825 // driver = "OpenGL";
2830 SetLoggingMode(stdOut, null);
2831 //SetLoggingMode(debug, null);
2833 settingsContainer.Load();
2834 #if defined(__unix__) || defined(__APPLE__)
2835 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2837 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2839 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2843 desktop.text = titleECEREIDE;
2846 for(c = 1; c<app.argc; c++)
2848 char fullPath[MAX_LOCATION];
2849 GetWorkingDir(fullPath, MAX_LOCATION);
2850 PathCat(fullPath, app.argv[c]);
2851 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2858 IDEMainFrame ideMainFrame { };
2860 define app = ((IDEApp)__thisModule);
2862 define titleECEREIDE = $"ECERE IDE (Debug)";
2864 define titleECEREIDE = $"ECERE IDE";