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 enum OpenCreateIfFails { no, yes, something, whatever };
56 enum OpenMethod { normal, add };
58 static FileFilter fileFilters[] =
61 "C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)",
62 "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx"
65 "Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)",
69 "C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)",
73 "Text files (*.txt, *.text, *.nfo, *.info)",
74 "txt, text, nfo, info"
77 "Web files (*.html, *.htm, *.xhtml, *.css, *.php, *.js, *.jsi, *.rb, *.xml)",
78 "html, htm, xhtml, css, php, js, jsi, rb, xml"
81 "Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)",
82 "jpg, jpeg, bmp, pcx, png, gif"
85 "3D Studio Model Files (*.3ds)",
91 static FileType fileTypes[] =
93 { "Based on extension", null },
96 { "3D Studio Model", "3ds" }
99 static FileFilter projectFilters[] =
102 "Project Files (*.epj)",
107 static FileType projectTypes[] =
109 { "Project File", ProjectExtension },
112 static FileFilter findInFilesFileFilters[] =
115 "eC Files (*.ec, *.eh)",
119 "C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)",
120 "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx"
123 "Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)",
124 "eh, h, hpp, hh, hxx"
127 "C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)",
128 "ec, c, cpp, cc, cxx"
131 "Text files (*.txt)",
134 { "All files", null }
137 FileDialog ideFileDialog
139 type = multiOpen, text = "Open";
140 types = fileTypes, sizeTypes = sizeof(fileTypes), filters = fileFilters, sizeFilters = sizeof(fileFilters);
143 FileDialog ideProjectFileDialog
145 type = open, text = "Open Project";
146 types = projectTypes, sizeTypes = sizeof(projectTypes), filters = projectFilters, sizeFilters = sizeof(projectFilters);
149 GlobalSettingsDialog globalSettingsDialog
151 ideSettings = ideSettings;
152 settingsContainer = settingsContainer;
154 void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange)
156 switch(globalSettingsChange)
161 for(child = ide.firstChild; child; child = child.next)
163 if(child._class == class(CodeEditor))
165 CodeEditor codeEditor = (CodeEditor) child;
166 codeEditor.editBox.freeCaret = ideSettings.useFreeCaret;
167 // codeEditor.editBox.lineNumbers = ideSettings.showLineNumbers;
168 codeEditor.editBox.caretFollowsScrolling = ideSettings.caretFollowsScrolling;
169 codeEditor.OnPostCreate(); // Update editBox margin size
176 case compilerSettings:
178 ide.UpdateMakefiles();
185 void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
190 lineY = (line - 1) * lineH;
191 if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
193 Bitmap bitmap = resource.bitmap;
195 surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
202 nativeDecorations = true;
203 icon = { ":icon.png" };
204 text = titleECEREIDE;
205 background = Color { 85, 85, 85 };
206 borderStyle = sizable;
211 hasVertScroll = true;
212 hasHorzScroll = true;
218 anchor = { top = 0, right = 0, bottom = 0 };
221 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
225 MenuItem * driverItems, * skinItems;
226 StatusField pos { width = 150 };
227 StatusField ovr, caps, num;
229 BitmapResource back { ":ecereBack.jpg", window = this };
230 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
231 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
232 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
233 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
234 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
235 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
236 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
237 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
238 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
239 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
241 Debugger debugger { };
243 ProjectView projectView;
245 OutputView outputView
249 void OnGotoError(char * line)
254 void OnCodeLocationParseAndGoTo(char * line)
256 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
259 bool OnKeyDown(Key key, unichar ch)
264 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
265 ide.ShowCodeEditor();
268 ide.projectView.stopBuild = true;
272 OutputView::OnKeyDown(key, ch);
279 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
282 ide.RepositionWindows(false);
286 bool OnClose(bool parentClosing)
290 ide.RepositionWindows(false);
291 return parentClosing;
295 CallStackView callStackView
297 parent = this, font = { panelFont.faceName, panelFont.size };
299 void OnGotoLine(char * line)
302 stackLvl = atoi(line);
303 ide.debugger.GoToStackFrameLine(stackLvl, true);
306 void OnSelectFrame(int lineNumber)
308 ide.debugger.SelectFrame(lineNumber);
311 void OnToggleBreakpoint()
313 Debugger debugger = ide.debugger;
314 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
316 int line = debugger.activeFrame.line;
317 char name[MAX_LOCATION];
319 // TOFIX: Improve on this, don't use only filename, make a function
320 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
321 if(ide && ide.workspace)
323 for(p : ide.workspace.projects)
325 if(p.topNode.Find(name, false))
333 for(p : ide.workspace.projects)
335 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
343 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
346 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
347 if(codeEditor) { codeEditor.Update(null); Activate(); }
352 bool OnKeyDown(Key key, unichar ch)
356 case escape: ide.ShowCodeEditor(); break;
361 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
364 ide.RepositionWindows(false);
368 bool OnClose(bool parentClosing)
372 ide.RepositionWindows(false);
373 return parentClosing;
376 void OnRedraw(Surface surface)
379 int lineCursor, lineTopFrame, activeThread, hitThread;
380 int lineH, scrollY, boxH;
382 Breakpoint bp = null;
383 Debugger debugger = ide.debugger;
384 Frame activeFrame = debugger.activeFrame;
387 scrollY = editBox.scroll.y;
388 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
390 activeThread = debugger.activeThread;
391 hitThread = debugger.hitThread;
392 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
394 if(activeFrame && activeFrame.absoluteFile)
396 for(i : ide.workspace.breakpoints; i.type == user)
398 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
399 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
400 activeFrame.line == i.line)
409 DrawLineMarginIcon(surface,
410 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
411 lineCursor /*1*/, lineH, scrollY, boxH);
414 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
415 DrawLineMarginIcon(surface,
416 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
417 1, lineH, scrollY, boxH);
419 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
420 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
421 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
423 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
424 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
425 if(editBox.horzScroll && editBox.horzScroll.visible)
427 surface.SetBackground(control);
428 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
433 WatchesView watchesView { parent = this };
434 ThreadsView threadsView
436 parent = this, font = { panelFont.faceName, panelFont.size };
438 bool OnKeyDown(Key key, unichar ch)
442 case escape: ide.ShowCodeEditor(); break;
447 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
450 ide.RepositionWindows(false);
454 bool OnClose(bool parentClosing)
458 ide.RepositionWindows(false);
459 return parentClosing;
462 void OnSelectThread(int threadId)
465 ide.debugger.SelectThread(threadId);
468 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
471 Debugger debugger = ide.debugger;
472 *activeThread = debugger.activeThread;
473 *hitThread = debugger.hitThread;
474 *signalThread = debugger.signalThread;
479 BreakpointsView breakpointsView { parent = this };
481 ToolBox toolBox { parent = this };
482 Sheet sheet { parent = this };
485 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
487 Menu fileMenu { menu, "File", f };
490 fileMenu, "New", n, ctrlN;
491 bool NotifySelect(MenuItem selection, Modifiers mods)
493 Window document = (Window)NewCodeEditor(this, normal, false);
494 document.NotifySaved = DocumentSaved;
498 MenuItem fileOpenItem
500 fileMenu, "Open...", o, ctrlO;
501 bool NotifySelect(MenuItem selection, Modifiers mods)
503 if(!projectView && ideSettings.ideFileDialogLocation)
504 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
507 if(ideFileDialog.Modal() == ok)
509 bool gotWhatWeWant = false;
511 int numSelections = ideFileDialog.numSelections;
512 char ** multiFilePaths = ideFileDialog.multiFilePaths;
514 for(c = 0; c < numSelections; c++)
516 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
517 gotWhatWeWant = true;
520 MessageBox { type = yesNo, /*master = this, */text = "Error opening file",
521 contents = "Open a different file?" }.Modal() == no)
523 if(!projectView && gotWhatWeWant)
524 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
534 MenuItem fileCloseItem { fileMenu, "Close", c, ctrlF4, NotifySelect = MenuFileClose };
535 MenuDivider { fileMenu };
536 MenuItem fileSaveItem { fileMenu, "Save", s, ctrlS };
537 MenuItem fileSaveAsItem { fileMenu, "Save As...", a };
538 MenuItem fileSaveAllItem { fileMenu, "Save All", l, NotifySelect = MenuFileSaveAll };
539 MenuDivider { fileMenu };
542 fileMenu, "Find In Files...", f, Key { f, ctrl = true , shift = true };
543 bool NotifySelect(MenuItem selection, Modifiers mods)
545 findInFilesDialog.replaceMode = false;
546 findInFilesDialog.Show();
550 MenuItem replaceInFiles
552 fileMenu, "Replace In Files...", e, Key { r, ctrl = true , shift = true };
553 bool NotifySelect(MenuItem selection, Modifiers mods)
555 findInFilesDialog.replaceMode = true;
556 findInFilesDialog.Show();
560 MenuDivider { fileMenu };
561 MenuItem globalSettingsItem
563 fileMenu, "Global Settings...", g;
564 bool NotifySelect(MenuItem selection, Modifiers mods)
566 // globalSettingsDialog.master = this;
567 if(ide.workspace && ide.workspace.compiler)
568 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
569 else if(ideSettings.defaultCompiler)
570 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
571 globalSettingsDialog.Modal();
575 MenuDivider { fileMenu };
576 Menu recentFiles { fileMenu, "Recent Files", r };
577 Menu recentProjects { fileMenu, "Recent Projects", p };
578 MenuDivider { fileMenu };
579 MenuItem exitItem { fileMenu, "Exit", x, altF4, NotifySelect = MenuFileExit };
581 bool FileRecentFile(MenuItem selection, Modifiers mods)
584 for(file : ideSettings.recentFiles)
586 if(id == selection.id)
588 OpenFile(file, normal, true, null, no, normal);
596 bool FileRecentProject(MenuItem selection, Modifiers mods)
599 for(file : ideSettings.recentProjects)
601 if(id == selection.id)
603 OpenFile(file, normal, true, null, no, normal);
611 MenuPlacement editMenu { menu, "Edit", e };
613 Menu projectMenu { menu, "Project", p };
614 MenuItem projectNewItem
616 projectMenu, "New...", n, Key { n, true, true };
617 bool NotifySelect(MenuItem selection, Modifiers mods)
619 if(!DontTerminateDebugSession("New Project"))
620 if(MenuWindowCloseAll(null, 0))
622 NewProjectDialog newProjectDialog;
626 projectView.visible = false;
627 if(!projectView.Destroy(0))
631 newProjectDialog = { master = this };
632 newProjectDialog.Modal();
635 ideSettings.AddRecentProject(projectView.fileName);
636 ide.UpdateRecentMenus();
637 settingsContainer.Save();
643 MenuItem projectOpenItem
645 projectMenu, "Open...", o, Key { o, true, true };
646 bool NotifySelect(MenuItem selection, Modifiers mods)
648 if(ideSettings.ideProjectFileDialogLocation)
649 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
651 if(ideProjectFileDialog.Modal() == ok)
653 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
654 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
659 MenuItem projectQuickItem
661 projectMenu, "Quick...", q, f7;
662 bool NotifySelect(MenuItem selection, Modifiers mods)
665 QuickProjectDialog{ this }.Modal();
669 MenuItem projectAddItem
671 projectMenu, "Add project to workspace...", a, Key { a, true, true };
673 bool NotifySelect(MenuItem selection, Modifiers mods)
675 if(ideSettings.ideProjectFileDialogLocation)
676 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
680 if(ideProjectFileDialog.Modal() == ok)
682 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
684 if(MessageBox { type = yesNo, /*master = this, */text = "Error opening project file",
685 contents = "Add a different project?" }.Modal() == no)
696 MenuItem projectCloseItem
698 projectMenu, "Close", c, disabled = true;
699 bool NotifySelect(MenuItem selection, Modifiers mods)
703 if(!ide.DontTerminateDebugSession("Project Close"))
705 if(findInFilesDialog)
706 findInFilesDialog.SearchStop();
707 projectView.visible = false;
708 if(projectView.Destroy(0))
709 MenuWindowCloseAll(null, 0);
711 char workingDir[MAX_LOCATION];
712 GetWorkingDir(workingDir, MAX_LOCATION);
713 findInFilesDialog.currentDirectory = workingDir;
720 MenuDivider { projectMenu };
721 MenuItem activeCompilerItem
723 projectMenu, "Active Compiler...", g, /*altF5, */disabled = true;
724 bool NotifySelect(MenuItem selection, Modifiers mods)
726 projectView.MenuCompiler(null, mods);
730 MenuItem projectActiveConfigItem
732 projectMenu, "Active Configuration...", g, altF5, disabled = true;
733 bool NotifySelect(MenuItem selection, Modifiers mods)
735 projectView.MenuConfig(projectView.active ? selection : null, mods);
739 MenuItem projectSettingsItem
741 projectMenu, "Settings...", s, altF7, disabled = true;
742 bool NotifySelect(MenuItem selection, Modifiers mods)
744 projectView.MenuSettings(projectView.active ? selection : null, mods);
748 MenuDivider { projectMenu };
749 MenuItem projectBrowseFolderItem
751 projectMenu, "Browse Project Folder", p, disabled = true;
752 bool NotifySelect(MenuItem selection, Modifiers mods)
755 projectView.MenuBrowseFolder(null, mods);
759 MenuDivider { projectMenu };
760 MenuItem projectRunItem
762 projectMenu, "Run", r, ctrlF5, disabled = true;
763 bool NotifySelect(MenuItem selection, Modifiers mods)
766 projectView.Run(null, mods);
770 MenuItem projectBuildItem
772 projectMenu, "Build", b, f7, disabled = true;
773 bool NotifySelect(MenuItem selection, Modifiers mods)
776 projectView.ProjectBuild(projectView.active ? selection : null, mods);
780 MenuItem projectLinkItem
782 projectMenu, "Relink", l, disabled = true;
783 bool NotifySelect(MenuItem selection, Modifiers mods)
786 projectView.ProjectLink(projectView.active ? selection : null, mods);
790 MenuItem projectRebuildItem
792 projectMenu, "Rebuild", d, shiftF7, disabled = true;
793 bool NotifySelect(MenuItem selection, Modifiers mods)
796 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
800 MenuItem projectCleanItem
802 projectMenu, "Clean", e, disabled = true;
803 bool NotifySelect(MenuItem selection, Modifiers mods)
808 projectView.ProjectClean(projectView.active ? selection : null, mods);
813 MenuItem projectRegenerateItem
815 projectMenu, "Regenerate Makefile", m, disabled = true;
816 bool NotifySelect(MenuItem selection, Modifiers mods)
819 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
823 MenuItem projectCompileItem;
824 Menu debugMenu { menu, "Debug", d };
825 MenuItem debugStartResumeItem
827 debugMenu, "Start", s, f5, disabled = true;
828 NotifySelect = MenuDebugStart;
830 bool MenuDebugStart(MenuItem selection, Modifiers mods)
834 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
835 if(!projectView.DebugStart())
836 debugStartResumeItem.disabled = false; // same exception
840 bool MenuDebugResume(MenuItem selection, Modifiers mods)
843 projectView.DebugResume();
846 MenuItem debugRestartItem
848 debugMenu, "Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
849 bool NotifySelect(MenuItem selection, Modifiers mods)
852 projectView.DebugRestart();
856 MenuItem debugBreakItem
858 debugMenu, "Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
859 bool NotifySelect(MenuItem selection, Modifiers mods)
862 projectView.DebugBreak();
866 MenuItem debugStopItem
868 debugMenu, "Stop", p, shiftF5, disabled = true;
869 bool NotifySelect(MenuItem selection, Modifiers mods)
872 projectView.DebugStop();
876 MenuDivider { debugMenu };
877 MenuItem debugStepIntoItem
879 debugMenu, "Step Into", i, f11, disabled = true;
880 bool NotifySelect(MenuItem selection, Modifiers mods)
883 projectView.DebugStepInto();
887 MenuItem debugStepOverItem
889 debugMenu, "Step Over", v, f10, disabled = true;
890 bool NotifySelect(MenuItem selection, Modifiers mods)
893 projectView.DebugStepOver(false);
897 MenuItem debugStepOutItem
899 debugMenu, "Step Out", o, shiftF11, disabled = true;
900 bool NotifySelect(MenuItem selection, Modifiers mods)
903 projectView.DebugStepOut(false);
907 MenuPlacement debugRunToCursorItem { debugMenu, "Run To Cursor", c };
908 MenuItem debugSkipStepOverItem
910 debugMenu, "Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
911 bool NotifySelect(MenuItem selection, Modifiers mods)
914 projectView.DebugStepOver(true);
918 MenuItem debugSkipStepOutItem
920 debugMenu, "Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
921 bool NotifySelect(MenuItem selection, Modifiers mods)
924 projectView.DebugStepOut(true);
928 MenuPlacement debugSkipRunToCursorItem { debugMenu, "Run To Cursor Skipping Breakpoints", u };
929 //MenuDivider { debugMenu };
930 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
931 MenuPlacement imageMenu { menu, "Image", i };
932 Menu viewMenu { menu, "View", v };
933 MenuItem viewProjectItem
935 viewMenu, "Project", j, alt0, disabled = true;
936 bool NotifySelect(MenuItem selection, Modifiers mods)
940 projectView.visible = true;
941 projectView.Activate();
946 MenuPlacement { viewMenu, "View Designer" };
947 MenuPlacement { viewMenu, "View Code" };
948 MenuPlacement { viewMenu, "View Properties" };
949 MenuPlacement { viewMenu, "View Methods" };
950 MenuItem viewDesignerItem
952 viewMenu, "View Designer", d, f8;
953 bool NotifySelect(MenuItem selection, Modifiers mods)
955 Window client = activeClient;
956 Class dataType = client._class;
957 if(!strcmp(dataType.name, "Designer"))
959 client.visible = true;
963 ((CodeEditor)client).ViewDesigner();
967 MenuItem viewCodeItem
969 viewMenu, "View Code", c, f8;
970 bool NotifySelect(MenuItem selection, Modifiers mods)
972 Window client = activeClient;
973 Class dataType = client._class;
974 if(!strcmp(dataType.name, "Designer"))
975 client = ((Designer)client).codeEditor;
978 // Do this after so the caret isn't moved yet...
979 client.visible = true;
983 MenuItem viewPropertiesItem
985 viewMenu, "View Properties", p, f4;
986 bool NotifySelect(MenuItem selection, Modifiers mods)
988 sheet.visible = true;
989 sheet.sheetSelected = properties;
994 MenuItem viewMethodsItem
996 viewMenu, "View Methods", m, f4;
997 bool NotifySelect(MenuItem selection, Modifiers mods)
999 sheet.visible = true;
1000 sheet.sheetSelected = methods;
1005 MenuItem viewToolBoxItem
1007 viewMenu, "View Toolbox", x, f12;
1008 bool NotifySelect(MenuItem selection, Modifiers mods)
1010 toolBox.visible = true;
1015 MenuItem viewOutputItem
1017 viewMenu, "Output", o, alt2;
1018 bool NotifySelect(MenuItem selection, Modifiers mods)
1024 MenuItem viewWatchesItem
1026 viewMenu, "Watches", w, alt3;
1027 bool NotifySelect(MenuItem selection, Modifiers mods)
1033 MenuItem viewThreadsItem
1035 viewMenu, "Threads", t, alt4;
1036 bool NotifySelect(MenuItem selection, Modifiers mods)
1042 MenuItem viewBreakpointsItem
1044 viewMenu, "Breakpoints", b, alt5;
1045 bool NotifySelect(MenuItem selection, Modifiers mods)
1047 breakpointsView.Show();
1051 MenuItem viewCallStackItem
1053 viewMenu, "Call Stack", s, alt7;
1054 bool NotifySelect(MenuItem selection, Modifiers mods)
1056 callStackView.Show();
1060 MenuItem viewAllDebugViews
1062 viewMenu, "All Debug Views", a, alt9;
1063 bool NotifySelect(MenuItem selection, Modifiers mods)
1068 callStackView.Show();
1069 breakpointsView.Show();
1073 #ifdef GDB_DEBUG_GUI
1074 MenuDivider { viewMenu };
1075 MenuItem viewGDBItem
1077 viewMenu, "GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1078 bool NotifySelect(MenuItem selection, Modifiers mods)
1085 MenuDivider { viewMenu };
1086 MenuItem viewColorPicker
1088 viewMenu, "Color Picker...", c, Key { c, ctrl = true , shift = true };
1089 bool NotifySelect(MenuItem selection, Modifiers mods)
1091 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1092 colorPicker.Create();
1096 MenuDivider { viewMenu };
1100 viewMenu, "Full Screen", f, checkable = true;
1102 bool NotifySelect(MenuItem selection, Modifiers mods)
1104 app.fullScreen ^= true;
1106 anchor = { 0, 0, 0, 0 };
1111 Menu driversMenu { viewMenu, "Graphics Driver", v };
1112 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1113 Menu windowMenu { menu, "Window", w };
1114 MenuItem { windowMenu, "Close All", l, NotifySelect = MenuWindowCloseAll };
1115 MenuDivider { windowMenu };
1116 MenuItem { windowMenu, "Next", n, f6, NotifySelect = MenuWindowNext };
1117 MenuItem { windowMenu, "Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1118 MenuDivider { windowMenu };
1119 MenuItem { windowMenu, "Cascade", c, NotifySelect = MenuWindowCascade };
1120 MenuItem { windowMenu, "Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1121 MenuItem { windowMenu, "Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1122 MenuItem { windowMenu, "Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1123 MenuDivider { windowMenu };
1124 MenuItem { windowMenu, "Windows...", w, NotifySelect = MenuWindowWindows };
1125 Menu helpMenu { menu, "Help", h };
1128 helpMenu, "API Reference", r, f1;
1129 bool NotifySelect(MenuItem selection, Modifiers mods)
1131 Execute("documentor");
1135 MenuDivider { helpMenu };
1138 helpMenu, "About...", a;
1139 bool NotifySelect(MenuItem selection, Modifiers mods)
1141 AboutIDE { /*master = this */}.Modal();
1146 property ToolBox toolBox
1148 get { return toolBox; }
1151 property Sheet sheet
1153 get { return sheet; }
1156 property Project project
1158 get { return projectView ? projectView.project : null; }
1161 property Workspace workspace
1163 get { return projectView ? projectView.workspace : null; }
1166 FindInFilesDialog findInFilesDialog
1168 master = this, parent = this;
1169 filters = findInFilesFileFilters, sizeFilters = sizeof(findInFilesFileFilters);
1173 #ifdef GDB_DEBUG_GUI
1176 master = this, parent = this;
1177 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1179 void OnCommand(char * string)
1182 ide.debugger.SendGDBCommand(string);
1187 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1189 //app.driver = app.drivers[selection.id];
1191 app.driver = selection.id ? "OpenGL" : "X";
1193 app.driver = selection.id ? "OpenGL" : "GDI";
1195 delete ideSettings.displayDriver;
1196 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1198 settingsContainer.Save();
1199 //SetDriverAndSkin();
1203 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1205 app.skin = app.skins[selection.id];
1210 void SetDriverAndSkin()
1213 for(c = 0; c < app.numSkins; c++)
1214 if(!strcmp(app.skins[c], app.skin))
1216 skinItems[c].checked = true;
1219 for(c = 0; c < app.numDrivers; c++)
1220 if(!strcmp(app.drivers[c], app.driver))
1222 driverItems[c].checked = true;
1227 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1229 Project project = workspace.projects.firstIterator.data;
1230 projectView = ProjectView
1233 fileName = fileName;
1235 void NotifyDestroyed(Window window, DialogResult result)
1238 text = titleECEREIDE;
1243 projectView.Create();
1244 RepositionWindows(false);
1246 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1247 projectView.workspace = workspace;
1248 projectView.project = project;
1249 SetText("%s - %s", project.topNode.name, titleECEREIDE);
1253 ide.breakpointsView.LoadFromWorkspace();
1254 ide.watchesView.LoadFromWorkspace();
1257 char fileName[MAX_LOCATION];
1258 strcpy(fileName, project.topNode.path);
1259 PathCat(fileName, project.topNode.name);
1264 bool GetDebugMenusDisabled()
1268 Project project = projectView.project;
1270 if(project.targetType == executable)
1277 void RepositionWindows(bool expand)
1282 bool inDebugMode = debugger.isActive;
1283 bool callStackVisible = expand ? false : callStackView.visible;
1284 bool threadsVisible = expand ? false : threadsView.visible;
1285 bool watchesVisible = expand ? false : watchesView.visible;
1286 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1287 bool toolBoxVisible = toolBox.visible;
1288 bool outputVisible = expand ? false : outputView.visible;
1289 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1290 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1292 for(child = firstChild; child; child = child.next)
1294 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1295 child._class == class(Sheet) || child._class == class(ProjectView))
1297 Anchor anchor = child.anchor;
1298 anchor.top = topDistance;
1299 anchor.bottom = bottomDistance;
1300 if(child._class == class(CodeEditor) || child._class == class(Designer))
1302 anchor.right = toolBoxVisible ? 150 : 0;
1304 child.anchor = anchor;
1308 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1309 child._class == class(BreakpointsView))
1310 child.visible = false;
1313 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1318 bool ShowCodeEditor()
1321 activeClient.Activate();
1322 else if(projectView)
1324 projectView.visible = true;
1325 projectView.Activate();
1329 sheet.visible = true;
1335 bool ShouldStopBuild()
1337 return projectView.stopBuild;
1340 void DocumentSaved(Window document, char * fileName)
1342 ideSettings.AddRecentFile(fileName);
1343 ide.UpdateRecentMenus();
1344 settingsContainer.Save();
1347 bool Window::OnFileModified(FileChange fileChange, char * param)
1350 sprintf(temp, "The document %s was modified by another application.\n"
1351 "Would you like to reload it and lose your changes?", this.fileName);
1352 if(MessageBox { type = yesNo/*, master = this*//*.parent*/,
1353 text = "Document has been modified", contents = temp }.Modal() == yes)
1355 char * fileName = CopyString(this.fileName);
1356 WindowState state = this.state;
1357 Anchor anchor = this.anchor;
1358 Size size = this.size;
1360 this.modifiedDocument = false;
1362 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1365 this.anchor = anchor;
1367 this.SetState(state, true, 0);
1375 void UpdateMakefiles()
1379 for(prj : workspace.projects)
1381 bool first = prj == workspace.projects.firstIterator.data;
1382 projectView.ProjectUpdateMakefileForAllConfigs(prj, first, first);
1389 bool unavailable = !project;
1391 projectQuickItem.disabled = !unavailable;
1393 projectAddItem.disabled = unavailable;
1395 activeCompilerItem.disabled = unavailable;
1396 projectActiveConfigItem.disabled = unavailable;
1397 projectSettingsItem.disabled = unavailable;
1399 projectBrowseFolderItem.disabled = unavailable;
1401 viewProjectItem.disabled = unavailable;
1407 void AdjustBuildMenus()
1409 bool unavailable = project && projectView.buildInProgress;
1411 projectNewItem.disabled = unavailable;
1412 projectOpenItem.disabled = unavailable;
1414 unavailable = !project || projectView.buildInProgress;
1416 projectCloseItem.disabled = unavailable;
1418 projectRunItem.disabled = unavailable || project.targetType != executable;
1419 projectBuildItem.disabled = unavailable;
1420 projectLinkItem.disabled = unavailable;
1421 projectRebuildItem.disabled = unavailable;
1422 projectCleanItem.disabled = unavailable;
1423 projectRegenerateItem.disabled = unavailable;
1424 projectCompileItem.disabled = unavailable;
1427 void AdjustDebugMenus()
1429 bool unavailable = !project || project.targetType != executable ||
1430 projectView.buildInProgress == buildingMainProject;
1431 bool active = ide.debugger.isActive;
1432 bool executing = ide.debugger.state == running;
1433 //bool holding = ide.debugger.state == stopped;
1435 debugStartResumeItem.disabled = unavailable || executing;
1437 debugStartResumeItem.text = active ? "Resume" : "Start";
1438 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1440 debugBreakItem.disabled = unavailable || !executing;
1441 debugStopItem.disabled = unavailable || !active;
1442 debugRestartItem.disabled = unavailable || !active;
1444 debugStepIntoItem.disabled = unavailable || executing;
1445 debugStepOverItem.disabled = unavailable || executing;
1446 debugStepOutItem.disabled = unavailable || executing || !active;
1447 debugSkipStepOverItem.disabled = unavailable || executing;
1448 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1450 if((Designer)GetActiveDesigner())
1452 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1455 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1456 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1461 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1463 char tempString[MAX_LOCATION];
1464 strcpy(tempString, directory);
1465 if(saveSettings && !projectView)
1467 ideSettings.ideFileDialogLocation = directory;
1468 settingsContainer.Save();
1471 ideFileDialog.currentDirectory = tempString;
1472 codeEditorFileDialog.currentDirectory = tempString;
1473 codeEditorFormFileDialog.currentDirectory = tempString;
1476 void ChangeProjectFileDialogDirectory(char * directory)
1478 ideSettings.ideProjectFileDialogLocation = directory;
1479 settingsContainer.Save();
1482 Window FindWindow(char * filePath)
1484 Window document = null;
1486 // TOCHECK: Do we need to change slashes here?
1487 for(document = firstChild; document; document = document.next)
1489 char * fileName = document.fileName;
1490 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1492 document.visible = true;
1493 document.Activate();
1500 bool DontTerminateDebugSession(char * title)
1502 if(debugger.isActive)
1504 if(MessageBox { type = yesNo, /*master = ide, */
1505 contents = "Do you want to terminate the debugging session in progress?",
1506 text = title }.Modal() == no)
1509 MessageBox msg { type = yesNo, master = ide,
1510 contents = "Do you want to terminate the debugging session in progress?",
1512 if(msg.Modal() == no)
1524 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1526 char extension[MAX_EXTENSION] = "";
1527 Window document = null;
1528 bool isProject = false;
1529 bool needFileModified = true;
1530 char winFilePath[MAX_LOCATION];
1531 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1535 GetExtension(filePath, extension);
1539 strcpy(extension, type);
1541 if(strcmp(extension, ProjectExtension))
1543 for(document = firstChild; document; document = document.next)
1545 char * fileName = document.fileName;
1546 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1548 document.visible = true;
1549 document.Activate();
1555 if(createIfFails == whatever)
1557 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1559 if(openMethod == normal)
1561 if(DontTerminateDebugSession("Open Project"))
1564 if(MenuWindowCloseAll(null, 0))
1568 projectView.visible = false;
1569 projectView.Destroy(0);
1570 // Where did this come from? projectView = null;
1577 Workspace workspace = null;
1579 if(FileExists(filePath))
1581 if(!strcmp(extension, ProjectExtension))
1583 char workspaceFile[MAX_LOCATION];
1584 strcpy(workspaceFile, filePath);
1585 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1586 workspace = LoadWorkspace(workspaceFile, filePath);
1588 else if(!strcmp(extension, WorkspaceExtension))
1589 workspace = LoadWorkspace(filePath, null);
1592 //project = LoadProject(filePath);
1597 char absolutePath[MAX_LOCATION];
1598 CreateProjectView(workspace, filePath);
1599 document = projectView;
1601 workspace.DropInvalidBreakpoints();
1604 ide.projectView.ShowOutputBuildLog(true);
1605 ide.projectView.DisplayCompiler(false);
1608 char newWorkingDir[MAX_LOCATION];
1609 StripLastDirectory(filePath, newWorkingDir);
1610 ChangeFileDialogsDirectory(newWorkingDir, false);
1613 document.fileName = filePath;
1615 SetText("%s - %s", filePath, titleECEREIDE);
1617 // this crashes on starting ide with epj file, solution please?
1618 // app.UpdateDisplay();
1620 workspace.holdTracking = true;
1621 for(ofi : workspace.openedFiles)
1623 if(ofi.state != closed)
1625 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1628 char fileName[MAX_LOCATION];
1630 GetLastDirectory(ofi.path, fileName);
1631 node = projectView.project.topNode.Find(fileName, true);
1633 node.EnsureVisible();
1637 workspace.holdTracking = false;
1639 workspace.timer.Start();
1641 findInFilesDialog.mode = FindInFilesMode::project;
1642 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1645 char location[MAX_LOCATION];
1646 StripLastDirectory(ide.project.topNode.path, location);
1647 ChangeProjectFileDialogDirectory(location);
1651 if(projectView.debugger)
1652 projectView.debugger.EvaluateWatches();
1659 if(MessageBox { type = yesNo, parent = this, text = "Error opening project", contents = "Open a different project?" }.Modal() == yes)
1661 if(ideProjectFileDialog.Modal() == cancel)
1663 filePath = ideProjectFileDialog.filePath;
1664 GetExtension(filePath, extension);
1675 else if(openMethod == add)
1680 char slashFilePath[MAX_LOCATION];
1681 GetSlashPathBuffer(slashFilePath, filePath);
1682 for(p : workspace.projects)
1684 if(!fstrcmp(p.filePath, slashFilePath))
1692 MessageBox { type = ok, parent = parent, /*master = this, */text = "Same Project",
1693 contents = "This project is already present in workspace." }.Modal();
1697 prj = LoadProject(filePath);
1700 workspace.projects.Add(prj);
1702 projectView.AddNode(prj.topNode, null);
1703 workspace.modified = true;
1705 findInFilesDialog.AddProjectItem(prj);
1706 projectView.ProjectUpdateMakefileForAllConfigs(prj, true, true);
1707 // projectView is associated with the main project and not with the one just added but
1708 return projectView; // just to let the caller know something was opened
1716 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1717 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1718 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1720 if(FileExists(filePath))
1721 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1722 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1723 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1726 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1729 else if(!strcmp(extension, "3ds"))
1731 if(FileExists(filePath))
1732 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1733 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1734 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1738 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1741 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1742 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1743 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1744 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1745 !strcmp(extension, "js"))
1747 CodeEditor editor { parent = this, state = state, visible = false };
1748 editor.updatingCode = true;
1749 if(editor.LoadFile(filePath))
1752 editor.visible = true;
1756 needFileModified = false;
1760 CodeEditor editor { parent = this, state = state, visible = false };
1761 if(editor.LoadFile(filePath))
1764 editor.visible = true;
1768 needFileModified = false;
1771 if(document && (document._class == class(PictureEdit) ||
1772 document._class == class(ModelView)))
1777 document.fileName = filePath;
1778 if(workspace && !workspace.holdTracking)
1779 workspace.UpdateOpenedFileInfo(filePath, opened);
1783 if(!document && createIfFails != no)
1785 if(createIfFails != yes && !needFileModified &&
1786 MessageBox { type = yesNo, parent = this, text = filePath, contents = "File doesn't exist. Create?" }.Modal() == yes)
1787 createIfFails = yes;
1788 if(createIfFails == yes || createIfFails == whatever)
1790 document = (Window)NewCodeEditor(this, state, true);
1792 document.fileName = filePath;
1798 if(projectView && document._class == class(CodeEditor) && workspace)
1800 int lineNumber, position;
1802 CodeEditor editor = (CodeEditor)document;
1803 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
1804 editor.openedFileInfo.holdTracking = true;
1805 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
1806 position = Max(editor.openedFileInfo.position - 1, 0);
1807 editor.editBox.GoToLineNum(lineNumber);
1808 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
1809 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
1810 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
1811 editor.editBox.scroll = scroll;
1812 editor.openedFileInfo.holdTracking = false;
1815 if(needFileModified)
1816 document.OnFileModified = OnFileModified;
1817 document.NotifySaved = DocumentSaved;
1820 ideSettings.AddRecentProject(document.fileName);
1822 ideSettings.AddRecentFile(document.fileName);
1823 ide.UpdateRecentMenus();
1824 settingsContainer.Save();
1832 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
1833 /*bool Window::GenericDocumentOnClose(bool parentClosing)
1835 if(!parentClosing && ide.workspace)
1836 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1839 bool ModelView::ModelViewOnClose(bool parentClosing)
1841 if(!parentClosing && ide.workspace)
1842 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1845 bool PictureEdit::PictureEditOnClose(bool parentClosing)
1847 if(!parentClosing && ide.workspace)
1848 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1853 void OnUnloadGraphics(Window window)
1855 display.ClearMaterials();
1856 display.ClearTextures();
1857 display.ClearMeshes();
1861 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
1863 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1864 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1868 bool OnKeyDown(Key key, unichar ch)
1873 projectView.Update(null);
1876 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1879 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1885 void GoToError(const char * line)
1888 projectView.GoToError(line);
1891 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
1894 char *colon = strchr(text, ':');
1895 char filePath[MAX_LOCATION];
1896 char completePath[MAX_LOCATION];
1897 int line = 0, col = 0;
1902 char * close = strchr(text, ')');
1906 strncpy(name, &text[4], close - text - 4);
1907 name[close - text - 4] = '\0';
1908 for(p : ide.workspace.projects)
1910 if(!strcmp(p.name, name))
1920 prj = project ? project : (dir ? null : ide.project);
1921 if(colon && (colon[1] == '/' || colon[1] == '\\'))
1923 path = (colon - 1 > path) ? colon - 1 : path;
1924 colon = strstr(colon + 1, ":");
1926 while(isspace(*path)) path++;
1929 strncpy(filePath, path, colon - path);
1930 filePath[colon - path] = '\0';
1931 line = atoi(colon + 1);
1932 colon = strstr(colon + 1, ":");
1934 col = atoi(colon + 1);
1936 else if(path - 1 >= path && *(path - 1) == '\"')
1938 colon = strchr(path, '\"');
1941 strncpy(filePath, path, colon - path);
1942 filePath[colon - path] = '\0';
1947 strcpy(completePath, prj.topNode.path);
1948 else if(dir && dir[0])
1949 strcpy(completePath, dir);
1951 completePath[0] = '\0';
1952 PathCat(completePath, filePath);
1954 if(FileExists(completePath).isFile)
1956 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
1957 if(codeEditor && line)
1959 EditBox editBox = codeEditor.editBox;
1960 editBox.GoToLineNum(line - 1);
1961 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
1966 void OnRedraw(Surface surface)
1968 Bitmap bitmap = back.bitmap;
1970 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
1973 void SheetSelected(SheetType sheetSelected)
1975 if(activeChild == sheet)
1977 if(sheetSelected == methods)
1979 viewPropertiesItem.accelerator = f4;
1980 viewPropertiesItem.parent = viewMenu;
1981 viewMethodsItem.parent = null;
1985 viewMethodsItem.accelerator = f4;
1986 viewMethodsItem.parent = viewMenu;
1987 viewPropertiesItem.parent = null;
1992 viewMethodsItem.parent = viewMenu;
1993 viewPropertiesItem.parent = viewMenu;
1994 if(sheetSelected == methods)
1996 viewMethodsItem.accelerator = f4;
1997 viewPropertiesItem.accelerator = 0;
2001 viewMethodsItem.accelerator = 0;
2002 viewPropertiesItem.accelerator = f4;
2007 void OnActivateClient(Window client, Window previous)
2009 //if(!client || client != previous)
2012 if(!client || client != previous)
2015 dataType = previous._class;
2016 if(previous && !strcmp(dataType.name, "CodeEditor"))
2018 ((CodeEditor)previous).UpdateFormCode();
2020 else if(previous && !strcmp(dataType.name, "Designer"))
2022 ((Designer)previous).codeEditor.UpdateFormCode();
2027 dataType = client._class;
2028 if(client && !strcmp(dataType.name, "CodeEditor"))
2030 CodeEditor codeEditor = (CodeEditor)client;
2031 SetPrivateModule(codeEditor.privateModule);
2032 SetCurrentContext(codeEditor.globalContext);
2033 SetTopContext(codeEditor.globalContext);
2034 SetGlobalContext(codeEditor.globalContext);
2036 SetDefines(&codeEditor.defines);
2037 SetImports(&codeEditor.imports);
2039 SetActiveDesigner(codeEditor.designer);
2041 sheet.codeEditor = codeEditor;
2042 toolBox.codeEditor = codeEditor;
2044 viewDesignerItem.parent = viewMenu;
2045 if(activeChild != codeEditor)
2047 viewCodeItem.parent = viewMenu;
2048 viewDesignerItem.accelerator = 0;
2049 viewCodeItem.accelerator = f8;
2053 viewCodeItem.parent = null;
2054 viewDesignerItem.accelerator = f8;
2057 else if(client && !strcmp(dataType.name, "Designer"))
2059 CodeEditor codeEditor = ((Designer)client).codeEditor;
2062 SetPrivateModule(codeEditor.privateModule);
2063 SetCurrentContext(codeEditor.globalContext);
2064 SetTopContext(codeEditor.globalContext);
2065 SetGlobalContext(codeEditor.globalContext);
2066 SetDefines(&codeEditor.defines);
2067 SetImports(&codeEditor.imports);
2071 SetPrivateModule(null);
2072 SetCurrentContext(null);
2073 SetTopContext(null);
2074 SetGlobalContext(null);
2079 SetActiveDesigner((Designer)client);
2081 sheet.codeEditor = codeEditor;
2082 toolBox.codeEditor = codeEditor;
2084 viewCodeItem.parent = viewMenu;
2085 if(activeChild != client)
2087 viewDesignerItem.parent = viewMenu;
2088 viewDesignerItem.accelerator = f8;
2089 viewCodeItem.accelerator = 0;
2093 viewDesignerItem.parent = null;
2094 viewCodeItem.accelerator = f8;
2100 sheet.codeEditor = null;
2101 toolBox.codeEditor = null;
2102 SetActiveDesigner(null);
2104 viewDesignerItem.parent = null;
2105 viewCodeItem.parent = null;
2108 SheetSelected(sheet.sheetSelected);
2111 projectCompileItem = null;
2116 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2118 CodeEditor codeEditor = (CodeEditor)client;
2119 EditBox editBox = codeEditor.editBox;
2121 statusBar.AddField(pos);
2123 caps = { width = 40, text = "CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2124 statusBar.AddField(caps);
2126 ovr = { width = 30, text = "OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2127 statusBar.AddField(ovr);
2129 num = { width = 30, text = "NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2130 statusBar.AddField(num);
2132 //statusBar.text = "Ready";
2134 if(projectView && projectView.project)
2136 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2140 sprintf(name, "Compile %s", node.name);
2141 projectCompileItem =
2143 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2145 bool NotifySelect(MenuItem selection, Modifiers mods)
2149 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2151 projectView.Compile(node);
2156 projectMenu.AddDynamic(projectCompileItem, null, false);
2162 caps = ovr = num = null;
2167 bool OnClose(bool parentClosing)
2169 //return !projectView.buildInProgress;
2170 if(projectView && projectView.buildInProgress)
2172 if(DontTerminateDebugSession("Close IDE"))
2174 if(findInFilesDialog)
2175 findInFilesDialog.SearchStop();
2178 workspace.timer.Stop();
2187 for(c = 1; c<app.argc; c++)
2189 char fullPath[MAX_LOCATION];
2190 GetWorkingDir(fullPath, MAX_LOCATION);
2191 PathCat(fullPath, app.argv[c]);
2192 if(FileExists(fullPath))
2193 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2200 // IS THIS NEEDED? WASN'T HERE BEFORE...
2203 projectView.visible = false;
2204 projectView.Destroy(0);
2207 #ifdef GDB_DEBUG_GUI
2208 gdbDialog.Destroy(0);
2213 void SetPath(bool projectsDirs)
2217 char * oldPaths[128];
2218 char oldList[MAX_LOCATION * 128];
2219 Array<String> newExePaths { };
2220 //Map<String, bool> exePathExists { };
2222 #if defined(__unix__) || defined(__APPLE__)
2223 Array<String> newLibPaths { };
2224 Map<String, bool> libPathExists { };
2226 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
2230 for(prj : workspace.projects)
2232 DirExpression targetDirExp;
2234 // SKIP FIRST PROJECT...
2235 if(prj == workspace.projects.firstIterator.data) continue;
2237 targetDirExp = prj.targetDir;
2239 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2243 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2244 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2248 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2249 if(cfg.targetType == sharedLibrary && cfg.debug)
2253 if(targetDirExp.dir)
2255 char buffer[MAX_LOCATION];
2256 #if defined(__WIN32__)
2257 Array<String> paths = newExePaths;
2259 Array<String> paths = newLibPaths;
2261 GetSystemPathBuffer(buffer, prj.topNode.path);
2262 PathCat(buffer, targetDirExp.dir);
2265 if(!fstrcmp(p, buffer))
2272 paths.Add(CopyString(buffer));
2274 delete targetDirExp;
2278 for(item : compiler.executableDirs)
2281 for(p : newExePaths)
2283 if(!fstrcmp(p, item))
2290 newExePaths.Add(CopySystemPath(item));
2293 GetEnvironment("PATH", oldList, sizeof(oldList));
2295 printf("Old value of PATH: %s\n", oldList);
2297 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2298 for(c = 0; c < count; c++)
2301 for(p : newExePaths)
2303 if(!fstrcmp(p, oldPaths[c]))
2310 newExePaths.Add(CopySystemPath(oldPaths[c]));
2314 for(path : newExePaths)
2315 len += strlen(path) + 1;
2316 newList = new char[len + 1];
2318 for(path : newExePaths)
2320 strcat(newList, path);
2321 strcat(newList, pathListSep);
2323 newList[len - 1] = '\0';
2324 SetEnvironment("PATH", newList);
2326 printf("New value of PATH: %s\n", newList);
2333 #if defined(__unix__) || defined(__APPLE__)
2335 for(item : compiler.libraryDirs)
2337 if(!libPathExists[item]) // fstrcmp should be used
2339 newLibPaths.Add(item);
2340 libPathExists[item] = true;
2344 #if defined(__APPLE__)
2345 GetEnvironment("DYLD_LIBRARY_PATH", oldList, sizeof(oldList));
2347 GetEnvironment("LD_LIBRARY_PATH", oldList, sizeof(oldList));
2350 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2352 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2353 for(c = 0; c < count; c++)
2355 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2357 newLibPaths.Add(oldPaths[c]);
2358 libPathExists[oldPaths[c]] = true;
2363 for(path : newLibPaths)
2364 len += strlen(path) + 1;
2365 newList = new char[len + 1];
2367 for(path : newLibPaths)
2369 strcat(newList, path);
2370 strcat(newList, pathListSep);
2372 newList[len - 1] = '\0';
2373 #if defined(__APPLE__)
2374 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2376 SetEnvironment("LD_LIBRARY_PATH", newList);
2379 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2384 delete libPathExists;
2389 void DestroyTemporaryProjectDir()
2391 if(tmpPrjDir && tmpPrjDir[0])
2393 if(FileExists(tmpPrjDir).isDirectory)
2394 DestroyDir(tmpPrjDir);
2395 property::tmpPrjDir = null;
2401 // Graphics Driver Menu
2405 app.currentSkin.selectionColor = selectionColor;
2406 app.currentSkin.selectionText = selectionText;
2410 driverItems = new MenuItem[app.numDrivers];
2411 for(c = 0; c < app.numDrivers; c++)
2413 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2414 driverItems[c].id = c;
2415 driverItems[c].isRadio = true;
2418 driverItems = new MenuItem[2];
2419 #if defined(__unix__)
2420 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2421 driverItems[0].id = 0;
2422 driverItems[0].isRadio = true;
2424 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2425 driverItems[0].id = 0;
2426 driverItems[0].isRadio = true;
2428 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2429 driverItems[1].id = 1;
2430 driverItems[1].isRadio = true;
2432 /* skinItems = new MenuItem[app.numSkins];
2433 for(c = 0; c < app.numSkins; c++)
2435 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2436 skinItems[c].id = c;
2437 skinItems[c].isRadio = true;
2440 ideFileDialog.master = this;
2441 ideProjectFileDialog.master = this;*/
2443 //SetDriverAndSkin();
2447 void UpdateRecentMenus()
2450 Menu fileMenu = menu.FindMenu("File");
2451 Menu recentFiles = fileMenu.FindMenu("Recent Files");
2452 Menu recentProjects = fileMenu.FindMenu("Recent Projects");
2453 char itemName[MAX_LOCATION + 4];
2456 recentFiles.Clear();
2459 for(recent : ideSettings.recentFiles)
2461 sprintf(itemName, "%d %s", 1 + c, recent);
2462 MakeSystemPath(itemName);
2463 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, null, true);
2467 recentProjects.Clear();
2469 for(recent : ideSettings.recentProjects)
2471 sprintf(itemName, "%d %s", 1 + c, recent);
2472 MakeSystemPath(itemName);
2473 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, null, true);
2485 void DestroyDir(char * path)
2487 RecursiveDeleteFolderFSI fsi { };
2492 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2494 bool preserveRootFolder;
2496 void OutFolder(char * folderPath, bool isRoot)
2498 if(!(preserveRootFolder && isRoot))
2499 RemoveDir(folderPath);
2502 bool OnFile(char * filePath)
2504 DeleteFile(filePath);
2509 class IDEApp : GuiApplication
2511 //driver = "Win32Console";
2512 // driver = "OpenGL";
2517 SetLoggingMode(stdOut, null);
2518 //SetLoggingMode(debug, null);
2520 settingsContainer.Load();
2521 #if defined(__unix__) || defined(__APPLE__)
2522 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2524 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2526 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2530 desktop.text = titleECEREIDE;
2533 for(c = 1; c<app.argc; c++)
2535 char fullPath[MAX_LOCATION];
2536 GetWorkingDir(fullPath, MAX_LOCATION);
2537 PathCat(fullPath, app.argv[c]);
2538 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2547 define app = ((IDEApp)__thisModule);
2549 define titleECEREIDE = "ECERE IDE (Debug)";
2551 define titleECEREIDE = "ECERE IDE";