2 public import static "ecere"
3 public import static "ec"
9 import "GlobalSettingsDialog"
10 import "NewProjectDialog"
11 import "FindInFilesDialog"
12 import "ActiveCompilerDialog"
19 import "ProjectActiveConfig"
20 import "ProjectConfig"
22 import "NodeProperties"
23 import "ProjectSettings"
35 import "BreakpointsView"
36 import "CallStackView"
47 import "FileSystemIterator"
49 #if defined(__WIN32__)
50 define pathListSep = ";";
52 define pathListSep = ":";
55 define maxPathLen = 65 * MAX_LOCATION;
57 class PathBackup : struct
64 oldPath = new char[maxPathLen];
65 oldLDPath = new char[maxPathLen];
67 GetEnvironment("PATH", oldPath, maxPathLen);
68 #if defined(__APPLE__)
69 GetEnvironment("DYLD_LIBRARY_PATH", oldLDPath, maxPathLen);
71 GetEnvironment("LD_LIBRARY_PATH", oldLDPath, maxPathLen);
77 SetEnvironment("PATH", oldPath);
78 #if defined(__APPLE__)
79 SetEnvironment("DYLD_LIBRARY_PATH", oldLDPath);
81 SetEnvironment("LD_LIBRARY_PATH", oldLDPath);
88 enum OpenCreateIfFails { no, yes, something, whatever };
89 enum OpenMethod { normal, add };
91 static Array<FileFilter> fileFilters
93 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
94 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
95 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
96 { $"Text files (*.txt, *.text, *.nfo, *.info)", "txt, text, nfo, info" },
97 { $"Web files (*.html, *.htm, *.xhtml, *.css, *.php, *.js, *.jsi, *.rb, *.xml)", "html, htm, xhtml, css, php, js, jsi, rb, xml" },
98 { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
99 { $"3D Studio Model Files (*.3ds)", "3ds" },
100 { $"All files", null }
103 static Array<FileType> fileTypes
105 { $"Based on extension", null },
108 { $"3D Studio Model", "3ds" }
111 static Array<FileFilter> projectFilters
113 { $"Project Files (*.epj)", ProjectExtension }
116 static Array<FileType> projectTypes
118 { $"Project File", ProjectExtension }
121 static Array<FileFilter> findInFilesFileFilters
123 { $"eC Files (*.ec, *.eh)", "ec, eh" },
124 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
125 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
126 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
127 { $"Text files (*.txt)", "txt" },
128 { $"All files", null }
131 FileDialog ideFileDialog
133 type = multiOpen, text = $"Open";
134 types = fileTypes.array, sizeTypes = fileTypes.count * sizeof(FileType), filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter);
137 define openProjectFileDialogTitle = $"Open Project";
138 define addProjectFileDialogTitle = $"Open Additional Project";
139 FileDialog ideProjectFileDialog
142 types = projectTypes.array, sizeTypes = projectTypes.count * sizeof(FileType), filters = projectFilters.array, sizeFilters = projectFilters.count * sizeof(FileFilter);
145 GlobalSettingsDialog globalSettingsDialog
147 ideSettings = ideSettings;
148 settingsContainer = settingsContainer;
150 void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange)
152 switch(globalSettingsChange)
157 for(child = ide.firstChild; child; child = child.next)
159 if(child._class == class(CodeEditor))
161 CodeEditor codeEditor = (CodeEditor) child;
162 codeEditor.editBox.freeCaret = ideSettings.useFreeCaret;
163 // codeEditor.editBox.lineNumbers = ideSettings.showLineNumbers;
164 codeEditor.editBox.caretFollowsScrolling = ideSettings.caretFollowsScrolling;
165 codeEditor.OnPostCreate(); // Update editBox margin size
172 case compilerSettings:
174 ide.UpdateMakefiles();
181 void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
186 lineY = (line - 1) * lineH;
187 if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
189 Bitmap bitmap = resource.bitmap;
191 surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
196 #define IDEItem(x) (&((IDEWorkSpace)0).x)
198 class IDEToolbar : ToolBar
202 ToolButton buttonNewFile { this, toolTip = $"New file", menuItemPtr = IDEItem(fileNewItem) };
204 ToolButton buttonOpenFile { this, toolTip = $"Open file", menuItemPtr = IDEItem(fileOpenItem) };
206 // ToolButton buttonCloseFile { this, toolTip = $"Close file", menuItemPtr = IDEItem(fileCloseItem) };
208 ToolButton buttonSaveFile { this, toolTip = $"Save file", menuItemPtr = IDEItem(fileSaveItem) };
210 ToolButton buttonSaveAllFile { this, toolTip = $"Save all", menuItemPtr = IDEItem(fileSaveAllItem) };
212 ToolSeparator separator1 { this };
221 // ToolSeparator separator2 { this };
223 /* Project options */
225 ToolButton buttonNewProject { this, toolTip = $"New project", menuItemPtr = IDEItem(projectNewItem) };
227 ToolButton buttonOpenProject { this, toolTip = $"Open project", menuItemPtr = IDEItem(projectOpenItem) };
228 // Add project to workspace
229 ToolButton buttonAddProject { this, toolTip = $"Add project to workspace", menuItemPtr = IDEItem(projectAddItem), disabled = true; };
231 // ToolButton buttonCloseProject { this, toolTip = $"Close project", menuItemPtr = IDEItem(projectCloseItem), disabled = true; };
233 ToolSeparator separator3 { this };
235 /* Build/Execution options */
237 ToolButton buttonBuild { this, toolTip = $"Build project", menuItemPtr = IDEItem(projectBuildItem), disabled = true; };
239 ToolButton buttonReLink { this, toolTip = $"Relink project", menuItemPtr = IDEItem(projectLinkItem), disabled = true; };
241 ToolButton buttonRebuild { this, toolTip = $"Rebuild project", menuItemPtr = IDEItem(projectRebuildItem), disabled = true; };
243 ToolButton buttonClean { this, toolTip = $"Clean project", menuItemPtr = IDEItem(projectCleanItem), disabled = true; };
245 // ToolButton buttonRealClean { this, toolTip = $"Real clean project", menuItemPtr = IDEItem(projectRealCleanItem), disabled = true; };
246 // Regenerate Makefile
247 ToolButton buttonRegenerateMakefile { this, toolTip = $"Regenerate Makefile", menuItemPtr = IDEItem(projectRegenerateItem), disabled = true; };
248 // Compile actual file
250 ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem), disabled = true; };
252 ToolSeparator separator4 { this };
256 ToolButton buttonDebugStartResume { this, toolTip = $"Start", menuItemPtr = IDEItem(debugStartResumeItem), disabled = true; };
258 ToolButton buttonDebugRestart { this, toolTip = $"Restart", menuItemPtr = IDEItem(debugRestartItem), disabled = true; };
260 ToolButton buttonDebugPause { this, toolTip = $"Break", menuItemPtr = IDEItem(debugBreakItem), disabled = true; };
262 ToolButton buttonDebugStop { this, toolTip = $"Stop", menuItemPtr = IDEItem(debugStopItem), disabled = true; };
264 //ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem) };
266 ToolButton buttonDebugStepInto { this, toolTip = $"Step Into", menuItemPtr = IDEItem(debugStepIntoItem), disabled = true; };
268 ToolButton buttonDebugStepOver { this, toolTip = $"Step Over", menuItemPtr = IDEItem(debugStepOverItem), disabled = true; };
270 ToolButton buttonDebugStepOut { this, toolTip = $"Step Out", menuItemPtr = IDEItem(debugStepOutItem), disabled = true; };
272 ToolButton buttonDebugSkipStepOver { this, toolTip = $"Step Over Skipping Breakpoints", menuItemPtr = IDEItem(debugSkipStepOverItem), disabled = true; };
275 class IDEMainFrame : Window
277 background = formColor;
278 borderStyle = sizable;
282 minClientSize = { 600, 300 };
284 icon = { ":icon.png" };
285 text = titleECEREIDE;
289 anchor = { top = 0, right = 0, bottom = 0 };
292 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
299 isActiveClient = true;
301 direction = vertical;
302 background = formColor;
303 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
311 ((IDEWorkSpace)master).toolBar = null;
314 IDEWorkSpace ideWorkSpace { stack, this, toolBar = toolBar };
317 define ide = ideMainFrame.ideWorkSpace;
319 class IDEWorkSpace : Window
321 background = Color { 85, 85, 85 };
324 hasVertScroll = true;
325 hasHorzScroll = true;
327 isActiveClient = true;
328 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
332 MenuItem * driverItems, * skinItems;
333 StatusField pos { width = 150 };
334 StatusField ovr, caps, num;
336 BitmapResource back { ":ecereBack.jpg", window = this };
337 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
338 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
339 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
340 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
341 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
342 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
343 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
344 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
345 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
346 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
348 Debugger debugger { };
350 ProjectView projectView;
352 OutputView outputView
356 void OnGotoError(char * line)
361 void OnCodeLocationParseAndGoTo(char * line)
363 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
366 bool OnKeyDown(Key key, unichar ch)
371 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
372 ide.ShowCodeEditor();
375 ide.projectView.stopBuild = true;
379 OutputView::OnKeyDown(key, ch);
386 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
389 ide.RepositionWindows(false);
393 bool OnClose(bool parentClosing)
397 ide.RepositionWindows(false);
398 return parentClosing;
402 CallStackView callStackView
404 parent = this, font = { panelFont.faceName, panelFont.size };
406 void OnGotoLine(char * line)
409 stackLvl = atoi(line);
410 ide.debugger.GoToStackFrameLine(stackLvl, true);
413 void OnSelectFrame(int lineNumber)
415 ide.debugger.SelectFrame(lineNumber);
418 void OnToggleBreakpoint()
420 Debugger debugger = ide.debugger;
421 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
423 int line = debugger.activeFrame.line;
424 char name[MAX_LOCATION];
426 // TOFIX: Improve on this, don't use only filename, make a function
427 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
428 if(ide && ide.workspace)
430 for(p : ide.workspace.projects)
432 if(p.topNode.Find(name, false))
440 for(p : ide.workspace.projects)
442 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
450 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
453 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
454 if(codeEditor) { codeEditor.Update(null); Activate(); }
459 bool OnKeyDown(Key key, unichar ch)
463 case escape: ide.ShowCodeEditor(); break;
468 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
471 ide.RepositionWindows(false);
475 bool OnClose(bool parentClosing)
479 ide.RepositionWindows(false);
480 return parentClosing;
483 void OnRedraw(Surface surface)
486 int lineCursor, lineTopFrame, activeThread, hitThread;
487 int lineH, scrollY, boxH;
489 Breakpoint bp = null;
490 Debugger debugger = ide.debugger;
491 Frame activeFrame = debugger.activeFrame;
494 scrollY = editBox.scroll.y;
495 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
497 activeThread = debugger.activeThread;
498 hitThread = debugger.hitThread;
499 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
501 if(activeFrame && activeFrame.absoluteFile)
503 for(i : ide.workspace.breakpoints; i.type == user)
505 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
506 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
507 activeFrame.line == i.line)
516 DrawLineMarginIcon(surface,
517 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
518 lineCursor /*1*/, lineH, scrollY, boxH);
521 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
522 DrawLineMarginIcon(surface,
523 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
524 1, lineH, scrollY, boxH);
526 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
527 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
528 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
530 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
531 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
532 if(editBox.horzScroll && editBox.horzScroll.visible)
534 surface.SetBackground(control);
535 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
540 WatchesView watchesView { parent = this };
541 ThreadsView threadsView
543 parent = this, font = { panelFont.faceName, panelFont.size };
545 bool OnKeyDown(Key key, unichar ch)
549 case escape: ide.ShowCodeEditor(); break;
554 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
557 ide.RepositionWindows(false);
561 bool OnClose(bool parentClosing)
565 ide.RepositionWindows(false);
566 return parentClosing;
569 void OnSelectThread(int threadId)
572 ide.debugger.SelectThread(threadId);
575 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
578 Debugger debugger = ide.debugger;
579 *activeThread = debugger.activeThread;
580 *hitThread = debugger.hitThread;
581 *signalThread = debugger.signalThread;
586 BreakpointsView breakpointsView { parent = this };
588 ToolBox toolBox { parent = this };
589 Sheet sheet { parent = this };
592 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
594 Menu fileMenu { menu, $"File", f, hasMargin = true };
597 fileMenu, $"New", n, ctrlN;
598 bitmap = { ":actions/docNew.png" };
599 bool NotifySelect(MenuItem selection, Modifiers mods)
601 Window document = (Window)NewCodeEditor(this, normal, false);
602 document.NotifySaved = DocumentSaved;
606 MenuItem fileOpenItem
608 fileMenu, $"Open...", o, ctrlO;
609 bitmap = { ":actions/docOpen.png" };
610 bool NotifySelect(MenuItem selection, Modifiers mods)
612 if(!projectView && ideSettings.ideFileDialogLocation)
613 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
616 if(ideFileDialog.Modal() == ok)
618 bool gotWhatWeWant = false;
620 int numSelections = ideFileDialog.numSelections;
621 char ** multiFilePaths = ideFileDialog.multiFilePaths;
623 for(c = 0; c < numSelections; c++)
625 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
626 gotWhatWeWant = true;
629 MessageBox { type = yesNo, master = this, text = $"Error opening file",
630 contents = $"Open a different file?" }.Modal() == no)
632 if(!projectView && gotWhatWeWant)
633 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
643 MenuItem fileCloseItem { fileMenu, $"Close", c, ctrlF4, NotifySelect = MenuFileClose };
644 MenuDivider { fileMenu };
645 MenuItem fileSaveItem { fileMenu, $"Save", s, ctrlS, bitmap = { ":actions/docSave.png" } };
646 MenuItem fileSaveAsItem { fileMenu, $"Save As...", a };
647 MenuItem fileSaveAllItem { fileMenu, $"Save All", l, NotifySelect = MenuFileSaveAll, bitmap = { ":actions/docSaveAll.png" } };
648 MenuDivider { fileMenu };
651 fileMenu, $"Find In Files...", f, Key { f, ctrl = true , shift = true };
652 bool NotifySelect(MenuItem selection, Modifiers mods)
654 findInFilesDialog.replaceMode = false;
655 findInFilesDialog.Show();
659 MenuItem replaceInFiles
661 fileMenu, $"Replace In Files...", e, Key { r, ctrl = true , shift = true };
662 bool NotifySelect(MenuItem selection, Modifiers mods)
664 findInFilesDialog.replaceMode = true;
665 findInFilesDialog.Show();
669 MenuDivider { fileMenu };
670 MenuItem globalSettingsItem
672 fileMenu, $"Global Settings...", g;
673 bool NotifySelect(MenuItem selection, Modifiers mods)
675 globalSettingsDialog.master = this;
676 if(ide.workspace && ide.workspace.compiler)
677 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
678 else if(ideSettings.defaultCompiler)
679 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
680 globalSettingsDialog.Modal();
684 MenuDivider { fileMenu };
685 Menu recentFiles { fileMenu, $"Recent Files", r };
686 Menu recentProjects { fileMenu, $"Recent Projects", p };
687 MenuDivider { fileMenu };
690 fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit;
692 bool NotifySelect(MenuItem selection, Modifiers mods)
694 ideMainFrame.Destroy(0);
699 bool FileRecentFile(MenuItem selection, Modifiers mods)
702 for(file : ideSettings.recentFiles)
704 if(id == selection.id)
706 OpenFile(file, normal, true, null, no, normal);
714 bool FileRecentProject(MenuItem selection, Modifiers mods)
717 for(file : ideSettings.recentProjects)
719 if(id == selection.id)
721 OpenFile(file, normal, true, null, no, normal);
729 MenuPlacement editMenu { menu, $"Edit", e };
731 Menu projectMenu { menu, $"Menu"."Project", p, hasMargin = true };
732 MenuItem projectNewItem
734 projectMenu, $"New...", n, Key { n, true, true };
735 bitmap = { ":actions/projNew.png" };
736 bool NotifySelect(MenuItem selection, Modifiers mods)
738 if(!DontTerminateDebugSession($"New Project"))
739 if(MenuWindowCloseAll(null, 0))
741 NewProjectDialog newProjectDialog;
745 projectView.visible = false;
746 if(!projectView.Destroy(0))
750 newProjectDialog = { master = this };
751 newProjectDialog.Modal();
754 ideSettings.AddRecentProject(projectView.fileName);
755 ide.UpdateRecentMenus();
756 settingsContainer.Save();
762 MenuItem projectOpenItem
764 projectMenu, $"Open...", o, Key { o, true, true };
765 bitmap = { ":actions/projOpen.png" };
766 bool NotifySelect(MenuItem selection, Modifiers mods)
768 if(ideSettings.ideProjectFileDialogLocation)
769 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
771 ideProjectFileDialog.text = openProjectFileDialogTitle;
772 if(ideProjectFileDialog.Modal() == ok)
774 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
775 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
780 MenuItem projectQuickItem
782 projectMenu, $"Quick...", q, f7;
783 bool NotifySelect(MenuItem selection, Modifiers mods)
786 QuickProjectDialog{ this }.Modal();
790 MenuItem projectAddItem
792 projectMenu, $"Add project to workspace...", a, Key { a, true, true };
793 bitmap = { ":actions/projAdd.png" };
795 bool NotifySelect(MenuItem selection, Modifiers mods)
797 if(ideSettings.ideProjectFileDialogLocation)
798 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
800 ideProjectFileDialog.text = addProjectFileDialogTitle;
803 if(ideProjectFileDialog.Modal() == ok)
805 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
807 if(MessageBox { type = yesNo, master = this, text = $"Error opening project file",
808 contents = $"Add a different project?" }.Modal() == no)
819 MenuItem projectCloseItem
821 projectMenu, $"Close", c, disabled = true;
822 bool NotifySelect(MenuItem selection, Modifiers mods)
826 if(!ide.DontTerminateDebugSession($"Project Close"))
828 if(findInFilesDialog)
829 findInFilesDialog.SearchStop();
830 projectView.visible = false;
831 if(projectView.Destroy(0))
832 MenuWindowCloseAll(null, 0);
834 char workingDir[MAX_LOCATION];
835 GetWorkingDir(workingDir, MAX_LOCATION);
836 findInFilesDialog.currentDirectory = workingDir;
837 ideMainFrame.text = titleECEREIDE;
844 MenuDivider { projectMenu };
845 MenuItem activeCompilerItem
847 projectMenu, $"Active Compiler...", g, /*altF5, */disabled = true;
848 bool NotifySelect(MenuItem selection, Modifiers mods)
850 projectView.MenuCompiler(null, mods);
854 MenuItem projectActiveConfigItem
856 projectMenu, $"Active Configuration...", g, altF5, disabled = true;
857 bool NotifySelect(MenuItem selection, Modifiers mods)
859 projectView.MenuConfig(projectView.active ? selection : null, mods);
863 MenuItem projectSettingsItem
865 projectMenu, $"Settings...", s, altF7, disabled = true;
866 bool NotifySelect(MenuItem selection, Modifiers mods)
868 projectView.MenuSettings(projectView.active ? selection : null, mods);
872 MenuDivider { projectMenu };
873 MenuItem projectBrowseFolderItem
875 projectMenu, $"Browse Project Folder", p, disabled = true;
876 bool NotifySelect(MenuItem selection, Modifiers mods)
879 projectView.MenuBrowseFolder(null, mods);
883 MenuDivider { projectMenu };
884 MenuItem projectRunItem
886 projectMenu, $"Run", r, ctrlF5, disabled = true;
887 bitmap = { ":actions/run.png" };
888 bool NotifySelect(MenuItem selection, Modifiers mods)
891 projectView.Run(null, mods);
895 MenuItem projectBuildItem
897 projectMenu, $"Build", b, f7, disabled = true;
898 bitmap = { ":actions/build.png" };
899 bool NotifySelect(MenuItem selection, Modifiers mods)
902 projectView.ProjectBuild(projectView.active ? selection : null, mods);
906 MenuItem projectLinkItem
908 projectMenu, $"Relink", l, disabled = true;
909 bitmap = { ":actions/relink.png" };
910 bool NotifySelect(MenuItem selection, Modifiers mods)
913 projectView.ProjectLink(projectView.active ? selection : null, mods);
917 MenuItem projectRebuildItem
919 projectMenu, $"Rebuild", d, shiftF7, disabled = true;
920 bitmap = { ":actions/rebuild.png" };
921 bool NotifySelect(MenuItem selection, Modifiers mods)
924 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
928 MenuItem projectCleanItem
930 projectMenu, $"Clean", e, disabled = true;
931 bitmap = { ":actions/clean.png" };
932 bool NotifySelect(MenuItem selection, Modifiers mods)
937 projectView.ProjectClean(projectView.active ? selection : null, mods);
942 MenuItem projectRealCleanItem
944 projectMenu, $"Real Clean", disabled = true;
945 bitmap = { ":actions/clean.png" };
946 bool NotifySelect(MenuItem selection, Modifiers mods)
951 projectView.ProjectRealClean(projectView.active ? selection : null, mods);
956 MenuItem projectRegenerateItem
958 projectMenu, $"Regenerate Makefile", m, disabled = true;
959 bitmap = { ":actions/regMakefile.png" };
960 bool NotifySelect(MenuItem selection, Modifiers mods)
963 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
967 MenuItem projectCompileItem;
968 Menu debugMenu { menu, $"Debug", d, hasMargin = true };
969 MenuItem debugStartResumeItem
971 debugMenu, $"Start", s, f5, disabled = true;
972 bitmap = { ":actions/debug.png" };
973 NotifySelect = MenuDebugStart;
975 bool MenuDebugStart(MenuItem selection, Modifiers mods)
979 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
980 if(!projectView.DebugStart())
981 debugStartResumeItem.disabled = false; // same exception
985 bool MenuDebugResume(MenuItem selection, Modifiers mods)
988 projectView.DebugResume();
991 MenuItem debugRestartItem
993 debugMenu, $"Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
994 bitmap = { ":actions/restart.png" };
995 bool NotifySelect(MenuItem selection, Modifiers mods)
998 projectView.DebugRestart();
1002 MenuItem debugBreakItem
1004 debugMenu, $"Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
1005 bitmap = { ":actions/pause.png" };
1006 bool NotifySelect(MenuItem selection, Modifiers mods)
1009 projectView.DebugBreak();
1013 MenuItem debugStopItem
1015 debugMenu, $"Stop", p, shiftF5, disabled = true;
1016 bitmap = { ":actions/stopDebug.png" };
1017 bool NotifySelect(MenuItem selection, Modifiers mods)
1020 projectView.DebugStop();
1024 MenuDivider { debugMenu };
1025 MenuItem debugStepIntoItem
1027 debugMenu, $"Step Into", i, f11, disabled = true;
1028 bitmap = { ":actions/stepInto.png" };
1029 bool NotifySelect(MenuItem selection, Modifiers mods)
1032 projectView.DebugStepInto();
1036 MenuItem debugStepOverItem
1038 debugMenu, $"Step Over", v, f10, disabled = true;
1039 bitmap = { ":actions/stepOver.png" };
1040 bool NotifySelect(MenuItem selection, Modifiers mods)
1043 projectView.DebugStepOver(false);
1047 MenuItem debugStepOutItem
1049 debugMenu, $"Step Out", o, shiftF11, disabled = true;
1050 bitmap = { ":actions/stepOut.png" };
1051 bool NotifySelect(MenuItem selection, Modifiers mods)
1054 projectView.DebugStepOut(false);
1058 MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
1059 MenuItem debugSkipStepOverItem
1061 debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
1062 bool NotifySelect(MenuItem selection, Modifiers mods)
1065 projectView.DebugStepOver(true);
1069 MenuItem debugSkipStepOutItem
1071 debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
1072 bitmap = { ":actions/skipBreaks.png" };
1073 bool NotifySelect(MenuItem selection, Modifiers mods)
1076 projectView.DebugStepOut(true);
1080 MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
1081 //MenuDivider { debugMenu };
1082 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
1083 MenuPlacement imageMenu { menu, $"Image", i };
1084 Menu viewMenu { menu, $"View", v };
1085 MenuItem viewProjectItem
1087 viewMenu, $"Project View", j, alt0, disabled = true;
1088 bool NotifySelect(MenuItem selection, Modifiers mods)
1092 projectView.visible = true;
1093 projectView.Activate();
1098 MenuPlacement { viewMenu, $"View Designer" };
1099 MenuPlacement { viewMenu, $"View Code" };
1100 MenuPlacement { viewMenu, $"View Properties" };
1101 MenuPlacement { viewMenu, $"View Methods" };
1102 MenuItem viewDesignerItem
1104 viewMenu, $"View Designer", d, f8;
1105 bool NotifySelect(MenuItem selection, Modifiers mods)
1107 Window client = activeClient;
1108 Class dataType = client._class;
1109 if(!strcmp(dataType.name, "Designer"))
1111 client.visible = true;
1115 ((CodeEditor)client).ViewDesigner();
1119 MenuItem viewCodeItem
1121 viewMenu, $"View Code", c, f8;
1122 bool NotifySelect(MenuItem selection, Modifiers mods)
1124 Window client = activeClient;
1125 Class dataType = client._class;
1126 if(!strcmp(dataType.name, "Designer"))
1127 client = ((Designer)client).codeEditor;
1130 // Do this after so the caret isn't moved yet...
1131 client.visible = true;
1135 MenuItem viewPropertiesItem
1137 viewMenu, $"View Properties", p, f4;
1138 bool NotifySelect(MenuItem selection, Modifiers mods)
1140 sheet.visible = true;
1141 sheet.sheetSelected = properties;
1146 MenuItem viewMethodsItem
1148 viewMenu, $"View Methods", m, f4;
1149 bool NotifySelect(MenuItem selection, Modifiers mods)
1151 sheet.visible = true;
1152 sheet.sheetSelected = methods;
1157 MenuItem viewToolBoxItem
1159 viewMenu, $"View Toolbox", x, f12;
1160 bool NotifySelect(MenuItem selection, Modifiers mods)
1162 toolBox.visible = true;
1167 MenuItem viewOutputItem
1169 viewMenu, $"Output", o, alt2;
1170 bool NotifySelect(MenuItem selection, Modifiers mods)
1176 MenuItem viewWatchesItem
1178 viewMenu, $"Watches", w, alt3;
1179 bool NotifySelect(MenuItem selection, Modifiers mods)
1185 MenuItem viewThreadsItem
1187 viewMenu, $"Threads", t, alt4;
1188 bool NotifySelect(MenuItem selection, Modifiers mods)
1194 MenuItem viewBreakpointsItem
1196 viewMenu, $"Breakpoints", b, alt5;
1197 bool NotifySelect(MenuItem selection, Modifiers mods)
1199 breakpointsView.Show();
1203 MenuItem viewCallStackItem
1205 viewMenu, $"Call Stack", s, alt7;
1206 bool NotifySelect(MenuItem selection, Modifiers mods)
1208 callStackView.Show();
1212 MenuItem viewAllDebugViews
1214 viewMenu, $"All Debug Views", a, alt9;
1215 bool NotifySelect(MenuItem selection, Modifiers mods)
1220 callStackView.Show();
1221 breakpointsView.Show();
1225 #ifdef GDB_DEBUG_GUI
1226 MenuDivider { viewMenu };
1227 MenuItem viewGDBItem
1229 viewMenu, $"GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1230 bool NotifySelect(MenuItem selection, Modifiers mods)
1237 MenuDivider { viewMenu };
1238 MenuItem viewColorPicker
1240 viewMenu, $"Color Picker...", c, Key { c, ctrl = true , shift = true };
1241 bool NotifySelect(MenuItem selection, Modifiers mods)
1243 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1244 colorPicker.Create();
1248 MenuDivider { viewMenu };
1252 viewMenu, "Full Screen", f, checkable = true;
1254 bool NotifySelect(MenuItem selection, Modifiers mods)
1256 app.fullScreen ^= true;
1258 anchor = { 0, 0, 0, 0 };
1263 Menu driversMenu { viewMenu, $"Graphics Driver", v };
1264 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1265 Menu windowMenu { menu, $"Window", w };
1266 MenuItem { windowMenu, $"Close All", l, NotifySelect = MenuWindowCloseAll };
1267 MenuDivider { windowMenu };
1268 MenuItem { windowMenu, $"Next", n, f6, NotifySelect = MenuWindowNext };
1269 MenuItem { windowMenu, $"Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1270 MenuDivider { windowMenu };
1271 MenuItem { windowMenu, $"Cascade", c, NotifySelect = MenuWindowCascade };
1272 MenuItem { windowMenu, $"Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1273 MenuItem { windowMenu, $"Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1274 MenuItem { windowMenu, $"Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1275 MenuDivider { windowMenu };
1276 MenuItem { windowMenu, $"Windows...", w, NotifySelect = MenuWindowWindows };
1277 Menu helpMenu { menu, $"Help", h };
1280 helpMenu, $"API Reference", r, f1;
1281 bool NotifySelect(MenuItem selection, Modifiers mods)
1283 Execute("documentor");
1287 MenuDivider { helpMenu };
1290 helpMenu, $"About...", a;
1291 bool NotifySelect(MenuItem selection, Modifiers mods)
1293 AboutIDE { master = this }.Modal();
1298 property ToolBox toolBox
1300 get { return toolBox; }
1303 property Sheet sheet
1305 get { return sheet; }
1308 property Project project
1310 get { return projectView ? projectView.project : null; }
1313 property Workspace workspace
1315 get { return projectView ? projectView.workspace : null; }
1318 FindInFilesDialog findInFilesDialog
1320 master = this, parent = this;
1321 filters = findInFilesFileFilters.array, sizeFilters = findInFilesFileFilters.count * sizeof(FileFilter);
1325 #ifdef GDB_DEBUG_GUI
1328 master = this, parent = this;
1329 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1331 void OnCommand(char * string)
1334 ide.debugger.SendGDBCommand(string);
1339 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1341 //app.driver = app.drivers[selection.id];
1343 app.driver = selection.id ? "OpenGL" : "X";
1345 app.driver = selection.id ? "OpenGL" : "GDI";
1347 delete ideSettings.displayDriver;
1348 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1350 settingsContainer.Save();
1351 //SetDriverAndSkin();
1355 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1357 app.skin = app.skins[selection.id];
1362 void SetDriverAndSkin()
1365 for(c = 0; c < app.numSkins; c++)
1366 if(!strcmp(app.skins[c], app.skin))
1368 skinItems[c].checked = true;
1371 for(c = 0; c < app.numDrivers; c++)
1372 if(!strcmp(app.drivers[c], app.driver))
1374 driverItems[c].checked = true;
1379 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1381 Project project = workspace.projects.firstIterator.data;
1382 projectView = ProjectView
1385 fileName = fileName;
1387 void NotifyDestroyed(Window window, DialogResult result)
1390 text = titleECEREIDE;
1395 projectView.Create();
1396 RepositionWindows(false);
1398 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1399 projectView.workspace = workspace;
1400 projectView.project = project;
1401 ideMainFrame.SetText("%s - %s", project.topNode.name, titleECEREIDE);
1405 ide.breakpointsView.LoadFromWorkspace();
1406 ide.watchesView.LoadFromWorkspace();
1408 findInFilesDialog.projectNodeField.userData = projectView;
1411 char fileName[MAX_LOCATION];
1412 strcpy(fileName, project.topNode.path);
1413 PathCat(fileName, project.topNode.name);
1418 bool GetDebugMenusDisabled()
1422 Project project = projectView.project;
1424 if(project.GetTargetType(project.config) == executable)
1431 void RepositionWindows(bool expand)
1436 bool inDebugMode = debugger.isActive;
1437 bool callStackVisible = expand ? false : callStackView.visible;
1438 bool threadsVisible = expand ? false : threadsView.visible;
1439 bool watchesVisible = expand ? false : watchesView.visible;
1440 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1441 bool toolBoxVisible = toolBox.visible;
1442 bool outputVisible = expand ? false : outputView.visible;
1443 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1444 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1446 for(child = firstChild; child; child = child.next)
1448 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1449 child._class == class(Sheet) || child._class == class(ProjectView))
1451 Anchor anchor = child.anchor;
1452 anchor.top = topDistance;
1453 anchor.bottom = bottomDistance;
1454 if(child._class == class(CodeEditor) || child._class == class(Designer))
1456 anchor.right = toolBoxVisible ? 150 : 0;
1458 child.anchor = anchor;
1462 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1463 child._class == class(BreakpointsView))
1464 child.visible = false;
1467 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1472 bool ShowCodeEditor()
1475 activeClient.Activate();
1476 else if(projectView)
1478 projectView.visible = true;
1479 projectView.Activate();
1483 sheet.visible = true;
1489 bool ShouldStopBuild()
1491 return projectView.stopBuild;
1494 void DocumentSaved(Window document, char * fileName)
1496 ideSettings.AddRecentFile(fileName);
1497 ide.UpdateRecentMenus();
1498 settingsContainer.Save();
1501 bool Window::OnFileModified(FileChange fileChange, char * param)
1504 sprintf(temp, $"The document %s was modified by another application.\n"
1505 "Would you like to reload it and lose your changes?", this.fileName);
1506 if(MessageBox { type = yesNo, master = this/*.parent*/,
1507 text = $"Document has been modified", contents = temp }.Modal() == yes)
1509 char * fileName = CopyString(this.fileName);
1510 WindowState state = this.state;
1511 Anchor anchor = this.anchor;
1512 Size size = this.size;
1514 this.modifiedDocument = false;
1516 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1519 this.anchor = anchor;
1521 this.SetState(state, true, 0);
1529 void UpdateMakefiles()
1533 for(prj : workspace.projects)
1535 bool first = prj == workspace.projects.firstIterator.data;
1536 projectView.ProjectUpdateMakefileForAllConfigs(prj, first, first);
1543 bool unavailable = !project;
1545 projectQuickItem.disabled = !unavailable;
1547 projectAddItem.disabled = unavailable;
1548 toolBar.buttonAddProject.disabled = unavailable;
1550 activeCompilerItem.disabled = unavailable;
1551 projectActiveConfigItem.disabled = unavailable;
1552 projectSettingsItem.disabled = unavailable;
1554 projectBrowseFolderItem.disabled = unavailable;
1556 viewProjectItem.disabled = unavailable;
1562 void AdjustBuildMenus()
1564 bool unavailable = project && projectView.buildInProgress;
1566 projectNewItem.disabled = unavailable;
1567 toolBar.buttonNewProject.disabled = unavailable;
1568 projectOpenItem.disabled = unavailable;
1569 toolBar.buttonOpenProject.disabled = unavailable;
1571 unavailable = !project || projectView.buildInProgress;
1573 projectCloseItem.disabled = unavailable;
1574 // toolBar.buttonCloseProject.disabled = unavailable;
1576 projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
1577 toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
1578 projectBuildItem.disabled = unavailable;
1579 toolBar.buttonBuild.disabled = unavailable;
1580 projectLinkItem.disabled = unavailable;
1581 toolBar.buttonReLink.disabled = unavailable;
1582 projectRebuildItem.disabled = unavailable;
1583 toolBar.buttonRebuild.disabled = unavailable;
1584 projectCleanItem.disabled = unavailable;
1585 toolBar.buttonClean.disabled = unavailable;
1586 projectRealCleanItem.disabled = unavailable;
1587 // toolBar.buttonRealClean.disabled = unavailable;
1588 projectRegenerateItem.disabled = unavailable;
1589 toolBar.buttonRegenerateMakefile.disabled = unavailable;
1590 projectCompileItem.disabled = unavailable;
1592 if(projectView && projectView.popupMenu && projectView.popupMenu.menu && projectView.popupMenu.created)
1595 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, 0); if(menu) menu.disabled = unavailable;
1596 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, 0); if(menu) menu.disabled = unavailable;
1597 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, 0); if(menu) menu.disabled = unavailable;
1598 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0); if(menu) menu.disabled = unavailable;
1599 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0); if(menu) menu.disabled = unavailable;
1600 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0); if(menu) menu.disabled = unavailable;
1601 projectView.popupMenu.Update(null);
1605 void AdjustDebugMenus()
1607 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1608 projectView.buildInProgress == buildingMainProject;
1609 bool active = ide.debugger.isActive;
1610 bool executing = ide.debugger.state == running;
1611 //bool holding = ide.debugger.state == stopped;
1613 debugStartResumeItem.disabled = unavailable || executing;
1614 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1615 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1618 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1619 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1622 debugBreakItem.disabled = unavailable || !executing;
1623 debugStopItem.disabled = unavailable || !active;
1624 debugRestartItem.disabled = unavailable || !active;
1627 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1628 toolBar.buttonDebugStop.disabled = unavailable || !active;
1629 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1632 debugStepIntoItem.disabled = unavailable || executing;
1633 debugStepOverItem.disabled = unavailable || executing;
1634 debugStepOutItem.disabled = unavailable || executing || !active;
1635 debugSkipStepOverItem.disabled = unavailable || executing;
1636 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1639 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1640 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1641 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1642 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1643 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1645 if((Designer)GetActiveDesigner())
1647 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1650 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1651 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1656 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1658 char tempString[MAX_LOCATION];
1659 strcpy(tempString, directory);
1660 if(saveSettings && !projectView)
1662 ideSettings.ideFileDialogLocation = directory;
1663 settingsContainer.Save();
1666 ideFileDialog.currentDirectory = tempString;
1667 codeEditorFileDialog.currentDirectory = tempString;
1668 codeEditorFormFileDialog.currentDirectory = tempString;
1671 void ChangeProjectFileDialogDirectory(char * directory)
1673 ideSettings.ideProjectFileDialogLocation = directory;
1674 settingsContainer.Save();
1677 Window FindWindow(char * filePath)
1679 Window document = null;
1681 // TOCHECK: Do we need to change slashes here?
1682 for(document = firstChild; document; document = document.next)
1684 char * fileName = document.fileName;
1685 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1687 document.visible = true;
1688 document.Activate();
1695 bool DontTerminateDebugSession(char * title)
1697 if(debugger.isActive)
1699 if(MessageBox { type = yesNo, master = ide,
1700 contents = $"Do you want to terminate the debugging session in progress?",
1701 text = title }.Modal() == no)
1704 MessageBox msg { type = yesNo, master = ide,
1705 contents = "Do you want to terminate the debugging session in progress?",
1707 if(msg.Modal() == no)
1719 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1721 char extension[MAX_EXTENSION] = "";
1722 Window document = null;
1723 bool isProject = false;
1724 bool needFileModified = true;
1725 char winFilePath[MAX_LOCATION];
1726 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1730 GetExtension(filePath, extension);
1734 strcpy(extension, type);
1736 if(strcmp(extension, ProjectExtension))
1738 for(document = firstChild; document; document = document.next)
1740 char * fileName = document.fileName;
1741 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1743 document.visible = true;
1745 document.Activate();
1751 if(createIfFails == whatever)
1753 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1755 if(openMethod == normal)
1757 if(DontTerminateDebugSession($"Open Project"))
1760 if(MenuWindowCloseAll(null, 0))
1764 projectView.visible = false;
1765 projectView.Destroy(0);
1766 // Where did this come from? projectView = null;
1773 Workspace workspace = null;
1775 if(FileExists(filePath))
1777 if(!strcmp(extension, ProjectExtension))
1779 char workspaceFile[MAX_LOCATION];
1780 strcpy(workspaceFile, filePath);
1781 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1782 workspace = LoadWorkspace(workspaceFile, filePath);
1784 else if(!strcmp(extension, WorkspaceExtension))
1785 workspace = LoadWorkspace(filePath, null);
1788 //project = LoadProject(filePath);
1793 char absolutePath[MAX_LOCATION];
1794 CreateProjectView(workspace, filePath);
1795 document = projectView;
1797 workspace.DropInvalidBreakpoints();
1800 ide.projectView.ShowOutputBuildLog(true);
1802 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1803 ide.projectView.DisplayCompiler(compiler, false);
1808 char newWorkingDir[MAX_LOCATION];
1809 StripLastDirectory(filePath, newWorkingDir);
1810 ChangeFileDialogsDirectory(newWorkingDir, false);
1813 document.fileName = filePath;
1815 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1817 // this crashes on starting ide with epj file, solution please?
1818 // app.UpdateDisplay();
1820 workspace.holdTracking = true;
1821 for(ofi : workspace.openedFiles)
1823 if(ofi.state != closed)
1825 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1828 char fileName[MAX_LOCATION];
1830 GetLastDirectory(ofi.path, fileName);
1831 node = projectView.project.topNode.Find(fileName, true);
1833 node.EnsureVisible();
1837 workspace.holdTracking = false;
1839 workspace.timer.Start();
1841 findInFilesDialog.mode = FindInFilesMode::project;
1842 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1845 char location[MAX_LOCATION];
1846 StripLastDirectory(ide.project.topNode.path, location);
1847 ChangeProjectFileDialogDirectory(location);
1851 if(projectView.debugger)
1852 projectView.debugger.EvaluateWatches();
1859 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1861 ideProjectFileDialog.text = openProjectFileDialogTitle;
1862 if(ideProjectFileDialog.Modal() == cancel)
1864 filePath = ideProjectFileDialog.filePath;
1865 GetExtension(filePath, extension);
1876 else if(openMethod == add)
1881 char slashFilePath[MAX_LOCATION];
1882 GetSlashPathBuffer(slashFilePath, filePath);
1883 for(p : workspace.projects)
1885 if(!fstrcmp(p.filePath, slashFilePath))
1893 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1894 contents = $"This project is already present in workspace." }.Modal();
1898 prj = LoadProject(filePath);
1901 workspace.projects.Add(prj);
1903 projectView.AddNode(prj.topNode, null);
1904 workspace.modified = true;
1906 findInFilesDialog.AddProjectItem(prj);
1907 projectView.ProjectUpdateMakefileForAllConfigs(prj, true, true);
1910 char location[MAX_LOCATION];
1911 StripLastDirectory(prj.topNode.path, location);
1912 ChangeProjectFileDialogDirectory(location);
1915 // projectView is associated with the main project and not with the one just added but
1916 return projectView; // just to let the caller know something was opened
1924 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1925 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1926 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1928 if(FileExists(filePath))
1929 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1930 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1931 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1934 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1937 else if(!strcmp(extension, "3ds"))
1939 if(FileExists(filePath))
1940 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1941 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1942 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1946 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1949 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1950 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1951 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1952 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1953 !strcmp(extension, "js"))
1955 CodeEditor editor { parent = this, state = state, visible = false };
1956 editor.updatingCode = true;
1957 if(editor.LoadFile(filePath))
1960 editor.visible = true;
1964 needFileModified = false;
1968 CodeEditor editor { parent = this, state = state, visible = false };
1969 if(editor.LoadFile(filePath))
1972 editor.visible = true;
1976 needFileModified = false;
1979 if(document && (document._class == class(PictureEdit) ||
1980 document._class == class(ModelView)))
1985 document.fileName = filePath;
1986 if(workspace && !workspace.holdTracking)
1987 workspace.UpdateOpenedFileInfo(filePath, opened);
1991 if(!document && createIfFails != no)
1993 if(createIfFails != yes && !needFileModified &&
1994 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
1995 createIfFails = yes;
1996 if(createIfFails == yes || createIfFails == whatever)
1998 document = (Window)NewCodeEditor(this, state, true);
2000 document.fileName = filePath;
2006 if(projectView && document._class == class(CodeEditor) && workspace)
2008 int lineNumber, position;
2010 CodeEditor editor = (CodeEditor)document;
2011 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2012 editor.openedFileInfo.holdTracking = true;
2013 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2014 position = Max(editor.openedFileInfo.position - 1, 0);
2015 editor.editBox.GoToLineNum(lineNumber);
2016 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2017 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2018 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2019 editor.editBox.scroll = scroll;
2020 editor.openedFileInfo.holdTracking = false;
2023 if(needFileModified)
2024 document.OnFileModified = OnFileModified;
2025 document.NotifySaved = DocumentSaved;
2028 ideSettings.AddRecentProject(document.fileName);
2030 ideSettings.AddRecentFile(document.fileName);
2031 ide.UpdateRecentMenus();
2032 settingsContainer.Save();
2040 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2041 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2043 if(!parentClosing && ide.workspace)
2044 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2047 bool ModelView::ModelViewOnClose(bool parentClosing)
2049 if(!parentClosing && ide.workspace)
2050 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2053 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2055 if(!parentClosing && ide.workspace)
2056 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2061 void OnUnloadGraphics(Window window)
2063 display.ClearMaterials();
2064 display.ClearTextures();
2065 display.ClearMeshes();
2069 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2071 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2072 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2076 bool OnKeyDown(Key key, unichar ch)
2081 projectView.Update(null);
2084 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2087 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2093 void GoToError(const char * line)
2096 projectView.GoToError(line);
2099 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2102 char *colon = strchr(text, ':');
2103 char filePath[MAX_LOCATION];
2104 char completePath[MAX_LOCATION];
2105 int line = 0, col = 0;
2110 char * close = strchr(text, ')');
2114 strncpy(name, &text[4], close - text - 4);
2115 name[close - text - 4] = '\0';
2116 for(p : ide.workspace.projects)
2118 if(!strcmp(p.name, name))
2128 prj = project ? project : (dir ? null : ide.project);
2129 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2131 path = (colon - 1 > path) ? colon - 1 : path;
2132 colon = strstr(colon + 1, ":");
2134 while(isspace(*path)) path++;
2137 strncpy(filePath, path, colon - path);
2138 filePath[colon - path] = '\0';
2139 line = atoi(colon + 1);
2140 colon = strstr(colon + 1, ":");
2142 col = atoi(colon + 1);
2144 else if(path - 1 >= path && *(path - 1) == '\"')
2146 colon = strchr(path, '\"');
2149 strncpy(filePath, path, colon - path);
2150 filePath[colon - path] = '\0';
2155 strcpy(completePath, prj.topNode.path);
2156 else if(dir && dir[0])
2157 strcpy(completePath, dir);
2159 completePath[0] = '\0';
2160 PathCat(completePath, filePath);
2162 if(FileExists(completePath).isFile)
2164 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2165 if(codeEditor && line)
2167 EditBox editBox = codeEditor.editBox;
2168 editBox.GoToLineNum(line - 1);
2169 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2174 void OnRedraw(Surface surface)
2176 Bitmap bitmap = back.bitmap;
2178 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2181 void SheetSelected(SheetType sheetSelected)
2183 if(activeChild == sheet)
2185 if(sheetSelected == methods)
2187 viewPropertiesItem.accelerator = f4;
2188 viewPropertiesItem.parent = viewMenu;
2189 viewMethodsItem.parent = null;
2193 viewMethodsItem.accelerator = f4;
2194 viewMethodsItem.parent = viewMenu;
2195 viewPropertiesItem.parent = null;
2200 viewMethodsItem.parent = viewMenu;
2201 viewPropertiesItem.parent = viewMenu;
2202 if(sheetSelected == methods)
2204 viewMethodsItem.accelerator = f4;
2205 viewPropertiesItem.accelerator = 0;
2209 viewMethodsItem.accelerator = 0;
2210 viewPropertiesItem.accelerator = f4;
2215 void OnActivateClient(Window client, Window previous)
2217 //if(!client || client != previous)
2220 if(!client || client != previous)
2223 dataType = previous._class;
2224 if(previous && !strcmp(dataType.name, "CodeEditor"))
2226 ((CodeEditor)previous).UpdateFormCode();
2228 else if(previous && !strcmp(dataType.name, "Designer"))
2230 ((Designer)previous).codeEditor.UpdateFormCode();
2235 dataType = client._class;
2236 if(client && !strcmp(dataType.name, "CodeEditor"))
2238 CodeEditor codeEditor = (CodeEditor)client;
2239 SetPrivateModule(codeEditor.privateModule);
2240 SetCurrentContext(codeEditor.globalContext);
2241 SetTopContext(codeEditor.globalContext);
2242 SetGlobalContext(codeEditor.globalContext);
2244 SetDefines(&codeEditor.defines);
2245 SetImports(&codeEditor.imports);
2247 SetActiveDesigner(codeEditor.designer);
2249 sheet.codeEditor = codeEditor;
2250 toolBox.codeEditor = codeEditor;
2252 viewDesignerItem.parent = viewMenu;
2253 if(activeChild != codeEditor)
2255 viewCodeItem.parent = viewMenu;
2256 viewDesignerItem.accelerator = 0;
2257 viewCodeItem.accelerator = f8;
2261 viewCodeItem.parent = null;
2262 viewDesignerItem.accelerator = f8;
2265 else if(client && !strcmp(dataType.name, "Designer"))
2267 CodeEditor codeEditor = ((Designer)client).codeEditor;
2270 SetPrivateModule(codeEditor.privateModule);
2271 SetCurrentContext(codeEditor.globalContext);
2272 SetTopContext(codeEditor.globalContext);
2273 SetGlobalContext(codeEditor.globalContext);
2274 SetDefines(&codeEditor.defines);
2275 SetImports(&codeEditor.imports);
2279 SetPrivateModule(null);
2280 SetCurrentContext(null);
2281 SetTopContext(null);
2282 SetGlobalContext(null);
2287 SetActiveDesigner((Designer)client);
2289 sheet.codeEditor = codeEditor;
2290 toolBox.codeEditor = codeEditor;
2292 viewCodeItem.parent = viewMenu;
2293 if(activeChild != client)
2295 viewDesignerItem.parent = viewMenu;
2296 viewDesignerItem.accelerator = f8;
2297 viewCodeItem.accelerator = 0;
2301 viewDesignerItem.parent = null;
2302 viewCodeItem.accelerator = f8;
2308 sheet.codeEditor = null;
2309 toolBox.codeEditor = null;
2310 SetActiveDesigner(null);
2312 viewDesignerItem.parent = null;
2313 viewCodeItem.parent = null;
2316 SheetSelected(sheet.sheetSelected);
2319 projectCompileItem = null;
2324 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2326 CodeEditor codeEditor = (CodeEditor)client;
2327 EditBox editBox = codeEditor.editBox;
2329 statusBar.AddField(pos);
2331 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2332 statusBar.AddField(caps);
2334 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2335 statusBar.AddField(ovr);
2337 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2338 statusBar.AddField(num);
2340 //statusBar.text = "Ready";
2342 if(projectView && projectView.project)
2344 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2348 sprintf(name, $"Compile %s", node.name);
2349 projectCompileItem =
2351 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2353 bool NotifySelect(MenuItem selection, Modifiers mods)
2357 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2359 projectView.Compile(node);
2364 projectMenu.AddDynamic(projectCompileItem, ide, false);
2370 caps = ovr = num = null;
2375 bool OnClose(bool parentClosing)
2377 //return !projectView.buildInProgress;
2378 if(projectView && projectView.buildInProgress)
2380 if(DontTerminateDebugSession($"Close IDE"))
2382 if(findInFilesDialog)
2383 findInFilesDialog.SearchStop();
2386 workspace.timer.Stop();
2389 ideMainFrame.Destroy(0);
2396 for(c = 1; c<app.argc; c++)
2398 char fullPath[MAX_LOCATION];
2399 char parentPath[MAX_LOCATION];
2400 char ext[MAX_EXTENSION];
2402 FileAttribs dirAttribs;
2403 GetWorkingDir(fullPath, MAX_LOCATION);
2404 PathCat(fullPath, app.argv[c]);
2405 StripLastDirectory(fullPath, parentPath);
2406 GetExtension(app.argv[c], ext);
2407 isProject = !strcmpi(ext, "epj");
2409 if(isProject && c > 1) continue;
2411 // Create directory for projects (only)
2412 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2414 if(isProject && !FileExists(fullPath))
2416 // The NewProject will handle directory creation
2417 /*if(!dirAttribs.isDirectory)
2419 MakeDir(parentPath);
2420 dirAttribs = FileExists(parentPath);
2422 if(dirAttribs.isDirectory)*/
2424 char name[MAX_LOCATION];
2425 NewProjectDialog newProjectDialog;
2429 projectView.visible = false;
2430 if(!projectView.Destroy(0))
2434 newProjectDialog = { master = this };
2436 strcpy(name, app.argv[c]);
2437 StripExtension(name);
2438 GetLastDirectory(name, name);
2439 newProjectDialog.projectName.contents = name;
2440 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2441 newProjectDialog.locationEditBox.path = parentPath;
2442 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2444 newProjectDialog.Modal();
2447 ideSettings.AddRecentProject(projectView.fileName);
2448 ide.UpdateRecentMenus();
2449 settingsContainer.Save();
2452 // Open only one project
2456 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2464 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2467 projectView.visible = false;
2468 projectView.Destroy(0);
2471 #ifdef GDB_DEBUG_GUI
2472 gdbDialog.Destroy(0);
2477 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2481 char * oldPaths[128];
2482 String oldList = new char[maxPathLen];
2483 Array<String> newExePaths { };
2484 //Map<String, bool> exePathExists { };
2486 #if defined(__unix__) || defined(__APPLE__)
2487 Array<String> newLibPaths { };
2488 Map<String, bool> libPathExists { };
2493 for(prj : workspace.projects)
2495 DirExpression targetDirExp;
2497 // SKIP FIRST PROJECT...
2498 if(prj == workspace.projects.firstIterator.data) continue;
2500 // NOTE: Right now the additional project config dir will be
2501 // obtained when the debugger is started, so toggling it
2502 // while building will change which library gets used.
2503 // To go with the initial state, e.g. when F5 was pressed,
2504 // we nould need to keep a list of all project's active
2505 // config upon startup.
2506 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2508 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2512 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2513 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2517 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2518 if(cfg.targetType == sharedLibrary && cfg.debug)
2522 if(targetDirExp.dir)
2524 char buffer[MAX_LOCATION];
2525 #if defined(__WIN32__)
2526 Array<String> paths = newExePaths;
2528 Array<String> paths = newLibPaths;
2530 GetSystemPathBuffer(buffer, prj.topNode.path);
2531 PathCat(buffer, targetDirExp.dir);
2534 if(!fstrcmp(p, buffer))
2541 paths.Add(CopyString(buffer));
2543 delete targetDirExp;
2547 for(item : compiler.executableDirs)
2550 for(p : newExePaths)
2552 if(!fstrcmp(p, item))
2559 newExePaths.Add(CopySystemPath(item));
2562 GetEnvironment("PATH", oldList, maxPathLen);
2564 printf("Old value of PATH: %s\n", oldList);
2566 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2567 for(c = 0; c < count; c++)
2570 for(p : newExePaths)
2572 if(!fstrcmp(p, oldPaths[c]))
2579 newExePaths.Add(CopySystemPath(oldPaths[c]));
2583 for(path : newExePaths)
2584 len += strlen(path) + 1;
2585 newList = new char[len + 1];
2587 for(path : newExePaths)
2589 strcat(newList, path);
2590 strcat(newList, pathListSep);
2592 newList[len - 1] = '\0';
2593 SetEnvironment("PATH", newList);
2595 printf("New value of PATH: %s\n", newList);
2602 #if defined(__unix__) || defined(__APPLE__)
2604 for(item : compiler.libraryDirs)
2606 if(!libPathExists[item]) // fstrcmp should be used
2608 newLibPaths.Add(item);
2609 libPathExists[item] = true;
2613 #if defined(__APPLE__)
2614 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2616 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2619 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2621 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2622 for(c = 0; c < count; c++)
2624 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2626 newLibPaths.Add(oldPaths[c]);
2627 libPathExists[oldPaths[c]] = true;
2632 for(path : newLibPaths)
2633 len += strlen(path) + 1;
2634 newList = new char[len + 1];
2636 for(path : newLibPaths)
2638 strcat(newList, path);
2639 strcat(newList, pathListSep);
2641 newList[len - 1] = '\0';
2642 #if defined(__APPLE__)
2643 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2645 SetEnvironment("LD_LIBRARY_PATH", newList);
2648 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2653 delete libPathExists;
2656 if(compiler.distccEnabled && compiler.distccHosts)
2657 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2662 void DestroyTemporaryProjectDir()
2664 if(tmpPrjDir && tmpPrjDir[0])
2666 if(FileExists(tmpPrjDir).isDirectory)
2667 DestroyDir(tmpPrjDir);
2668 property::tmpPrjDir = null;
2674 // Graphics Driver Menu
2678 app.currentSkin.selectionColor = selectionColor;
2679 app.currentSkin.selectionText = selectionText;
2683 driverItems = new MenuItem[app.numDrivers];
2684 for(c = 0; c < app.numDrivers; c++)
2686 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2687 driverItems[c].id = c;
2688 driverItems[c].isRadio = true;
2691 driverItems = new MenuItem[2];
2692 #if defined(__unix__)
2693 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2694 driverItems[0].id = 0;
2695 driverItems[0].isRadio = true;
2697 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2698 driverItems[0].id = 0;
2699 driverItems[0].isRadio = true;
2701 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2702 driverItems[1].id = 1;
2703 driverItems[1].isRadio = true;
2705 /* skinItems = new MenuItem[app.numSkins];
2706 for(c = 0; c < app.numSkins; c++)
2708 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2709 skinItems[c].id = c;
2710 skinItems[c].isRadio = true;
2713 ideFileDialog.master = this;
2714 ideProjectFileDialog.master = this;
2716 //SetDriverAndSkin();
2720 void UpdateRecentMenus()
2723 Menu fileMenu = menu.FindMenu($"File");
2724 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2725 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2726 char itemName[MAX_LOCATION + 4];
2729 recentFiles.Clear();
2732 for(recent : ideSettings.recentFiles)
2734 sprintf(itemName, "%d %s", 1 + c, recent);
2735 MakeSystemPath(itemName);
2736 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2740 recentProjects.Clear();
2742 for(recent : ideSettings.recentProjects)
2744 sprintf(itemName, "%d %s", 1 + c, recent);
2745 MakeSystemPath(itemName);
2746 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2759 void DestroyDir(char * path)
2761 RecursiveDeleteFolderFSI fsi { };
2766 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2768 bool preserveRootFolder;
2770 void OutFolder(char * folderPath, bool isRoot)
2772 if(!(preserveRootFolder && isRoot))
2773 RemoveDir(folderPath);
2776 bool OnFile(char * filePath)
2778 DeleteFile(filePath);
2783 class IDEApp : GuiApplication
2785 //driver = "Win32Console";
2786 // driver = "OpenGL";
2791 SetLoggingMode(stdOut, null);
2792 //SetLoggingMode(debug, null);
2794 settingsContainer.Load();
2795 #if defined(__unix__) || defined(__APPLE__)
2796 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2798 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2800 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2804 desktop.text = titleECEREIDE;
2807 for(c = 1; c<app.argc; c++)
2809 char fullPath[MAX_LOCATION];
2810 GetWorkingDir(fullPath, MAX_LOCATION);
2811 PathCat(fullPath, app.argv[c]);
2812 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2819 IDEMainFrame ideMainFrame { };
2821 define app = ((IDEApp)__thisModule);
2823 define titleECEREIDE = $"ECERE IDE (Debug)";
2825 define titleECEREIDE = $"ECERE IDE";