2 import "WorkspaceSettings"
3 import "ProjectTabSettings"
5 // import "SelectorBar"
7 static ProjectConfig config;
8 static Platform platform;
9 static ProjectNode currentNode;
10 static Project project;
12 static String MakeString(char * s, int len)
14 String string = new char[len+1];
15 memcpy(string, s, len);
20 class StringListBox : EditBox
22 textHorzScroll = true;
24 property Array<String> strings
43 Array<String> array { };
45 char * contents = property::contents;
49 for(c = 0; (ch = contents[c]); c++)
51 if(ch == ' ' && !quoted)
54 array.Add(MakeString(contents + start, c - start));
66 array.Add(MakeString(contents + start, c - start));
72 define dialogTitle = $"Project Settings";
73 static Color unfocusedSelectorColor { 70, 96, 166 };
74 class ProjectSettings : Window
77 background = formColor;
78 borderStyle = sizable;
79 minClientSize = { 650, 520 };
84 property Project project
89 projectTab.project = value;
92 buildTab.SelectNode(project.topNode, false);
94 if(project && project.topNode && project.topNode.name && project.topNode.name[0])
97 get { return ::project; }
100 property ProjectNode projectNode
102 set { buildTab.SelectNode(value, false); }
103 get { return currentNode; }
106 void UpdateDialogTitle()
108 //char * s = PrintString("Project Settings - ", project.topNode.fileName);
110 char * projectName = new char[strlen(project.topNode.name) + 1];
111 char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
112 char * config = buildTab.selectedConfigName;
113 char * platform = buildTab.selectedPlatformName;
114 char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 +
115 strlen(nodeName) + 2 + strlen(config) + 1 + strlen(platform) + 1 + 1];
116 strcpy(label, dialogTitle);
117 strcat(label, " - ");
118 strcpy(projectName, project.topNode.name);
119 StripExtension(projectName);
120 strcat(label, projectName);
121 if(currentNode && currentNode.type != project)
123 strcat(label, " - ");
124 strcat(label, nodeName);
126 if(strlen(config) || strlen(platform))
130 strcat(label, config);
131 if(strlen(config) && strlen(platform))
134 strcat(label, platform);
147 TabControl prjTabControl
149 this, background = formColor, anchor = { left = 8, top = 4, right = 8, bottom = 38 };
151 ProjectTab projectTab { this, tabControl = prjTabControl };
152 BuildTab buildTab { this, tabControl = prjTabControl };
153 WorkspaceTab workspaceTab { this, tabControl = prjTabControl };
157 this, size = { 80, 22 };
158 anchor = { right = 8, bottom = 8 };
159 text = $"Cancel", hotKey = escape, id = DialogResult::cancel;
161 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
163 if(prjTabControl.curTab.modifiedDocument)
165 DialogResult diagRes = MessageBox
167 type = okCancel, master = ide,
168 text = $"Lose Changes?",
169 contents = $"Are you sure you wish to discard changes made to the build options?"
173 if(prjTabControl.curTab == buildTab)
175 buildTab.RevertChanges();
176 buildTab.modifiedDocument = false;
178 if(prjTabControl.curTab == workspaceTab)
180 workspaceTab.modifiedDocument = false;
182 if(prjTabControl.curTab == projectTab)
184 projectTab.modifiedDocument = false;
186 Destroy(DialogResult::cancel);
190 Destroy(DialogResult::cancel);
196 this, size = { 80, 22 };
197 anchor = { right = 96, bottom = 8 };
198 text = $"OK", isDefault = true;
200 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
202 if(prjTabControl.curTab == buildTab && buildTab.modifiedDocument)
204 buildTab.modifiedDocument = false;
206 project.topNode.modified = true;
207 project.MarkChanges(buildTab.backupNode);
208 ide.projectView.modifiedDocument = true;
209 ide.projectView.Update(null);
211 if(prjTabControl.curTab == workspaceTab && workspaceTab.modifiedDocument)
213 workspaceTab.SaveChanges();
214 workspaceTab.modifiedDocument = false;
216 if(prjTabControl.curTab == projectTab && projectTab.modifiedDocument)
218 projectTab.SaveChanges();
219 projectTab.modifiedDocument = false;
221 Destroy(DialogResult::ok);
229 prjTabControl.curTab = buildTab;
234 #define OPTION(x) ((uint)(&((ProjectOptions)0).x))
236 // TOFIX: USING T INSTEAD OF Z HERE CAUSED US SOME CONFLICTS WITH T IN Array TEMPLATES
238 // the BlendFileConfigPlatformProjectOptions function and the GenericOptionTools class
239 // contain code that is closely matched to the following code
240 // output changing modification should be mirrored in both implementations
241 class OptionBox<class Z> : CommonControl
243 bool mergeValues, configReplaces;
252 property Window editor
258 editor.OnRightButtonDown = OptionBox_OnRightButtonDown;
259 chainKeyDown = (void *)editor.OnKeyDown;
260 editor.OnKeyDown = OptionBox_OnKeyDown;
264 property bool visible { set { editor.visible = value; } get { return editor.visible; } }
265 property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)this; } }
266 property Point position { set { editor.position = value; } }
267 property Size size { set { editor.size = value; } }
268 property Anchor anchor { set { editor.anchor = value; } }
269 property Key hotKey { set { editor.hotKey = value; } }
270 property char * text { set { editor.text = value; Window::text = value; } }
280 bool NotifySelect(MenuItem selection, Modifiers mods)
282 OptionBox ob = (OptionBox)id;
283 if(eClass_IsDerived(ob._class, class(CheckBoxForEnumOptionBox)))
286 for(slave = ob.master.firstSlave; slave; slave = slave.nextSlave)
288 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
289 ((OptionBox)slave).option == ob.option)
290 ((OptionBox)slave).Unset();
299 bool Window::OptionBox_OnRightButtonDown(int x, int y, Modifiers mods)
301 OptionBox ob = (OptionBox)id;
302 GuiApplication app = ((GuiApplication)__thisModule.application);
304 PopupMenu { null, this, menu = ob.clearMenu,
305 position = { absPosition.x + clientStart.x + x - app.desktop.position.x, absPosition.y + clientStart.y + y - app.desktop.position.y } }.Create();
309 bool Window::OptionBox_OnKeyDown(Key key, unichar ch)
311 OptionBox ob = (OptionBox)id;
312 if(key == Key { del, ctrl = true } || key == Key { keyPadDelete, ctrl = true })
317 return (((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
320 // code: 0 = not set anywhere, 1 = overridden here, 2 = inherited
321 void SetAttribs(int code)
326 for(c = Window::parent.firstChild; c; c = c.next)
328 if(eClass_IsDerived(c._class, class(Label)))
331 if(label.labeledWindow == this)
339 for(c = editor.firstChild; c; c = c.next)
341 if(eClass_IsDerived(c._class, class(Label)))
348 // control.foreground = foreground;
350 if(code == 0 || code == 1)
352 editor.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
353 editor.background = white;
357 Color foreground = 0x0F3F66;
358 int r = foreground.r, g = foreground.g, b = foreground.b;
362 editor.font = { editor.font.faceName, editor.font.size };
364 r = (int)(alpha * r + src.r * (1 - alpha));
365 g = (int)(alpha * g + src.g * (1 - alpha));
366 b = (int)(alpha * b + src.b * (1 - alpha));
368 r = Max(0,Min(255,r));
369 g = Max(0,Min(255,g));
370 b = Max(0,Min(255,b));
372 editor.background = Color { (byte) r, (byte) g, (byte) b };
377 label.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
378 //label.foreground = foreground;
382 virtual void FinalizeLoading();
384 virtual void LoadOption(ProjectOptions options);
385 virtual void RetrieveOption(ProjectOptions options, bool isCfgOrPlt);
386 virtual void UnsetOption(ProjectOptions options)
389 *(Z*)((byte *)options + option) = value;
392 virtual bool OptionSet(ProjectOptions options)
394 // TOFIX: If you get a crash here, it might be because JSON.ec must be after ProjectConfig.ec in the project files
395 // JSON.ec must also be before ProjectSettings.ec in the project files
396 if(*(Z*)((byte *)options + option))
400 // BUG: OptionCheck = OptionSet; // Overrides derived classes OptionCheck ?
402 virtual bool OptionCheck(ProjectOptions options)
404 return OptionSet(options);
407 void MarkBuildTabModified()
409 BuildTab buildTab = (BuildTab)master;
410 while(buildTab && buildTab._class != class(BuildTab))
411 buildTab = (BuildTab)buildTab.master;
412 if(buildTab) buildTab.modifiedDocument = true;
417 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
418 MarkBuildTabModified();
422 ProjectConfig c = null;
423 if(currentNode.configurations)
425 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
430 PlatformOptions p = null;
433 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
436 if(p.options && OptionSet(p.options))
437 UnsetOption(p.options);
438 if(p.options && p.options.isEmpty)
442 Iterator<PlatformOptions> it { c.platforms };
450 if(!c.platforms.count)
456 if(c.options && OptionSet(c.options))
457 UnsetOption(c.options);
458 if(c.options && c.options.isEmpty)
461 // DON'T DELETE PROJECT CONFIGS HERE!
462 if(!c.options && currentNode != project.topNode)
464 Iterator<ProjectConfig> it { currentNode.configurations };
472 if(!currentNode.configurations.count)
473 currentNode.configurations = null;
480 PlatformOptions p = null;
481 if(currentNode.platforms)
483 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
486 if(p.options && OptionSet(p.options))
487 UnsetOption(p.options);
488 if(p.options && p.options.isEmpty)
492 Iterator<PlatformOptions> it { currentNode.platforms };
500 if(!currentNode.platforms.count)
501 currentNode.platforms = null;
507 if(currentNode.options && OptionSet(currentNode.options))
508 UnsetOption(currentNode.options);
509 if(currentNode.options && currentNode.options.isEmpty)
511 // delete currentNode.options;
512 // Property will free:
513 currentNode.options = null;
519 void FigureOutInherited()
522 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
523 bool skipped = false;
524 for(node = currentNode; node; node = node.parent)
526 bool configXplatformSet = false;
527 if(config && node.configurations)
529 for(c : node.configurations; !strcmpi(c.name, config.name))
531 if(platform && c.platforms)
533 for(p : c.platforms; !strcmpi(p.name, platformName))
535 if(p.options && OptionSet(p.options))
538 LoadOption(p.options);
540 configXplatformSet = true;
546 if(skipped && c.options && OptionSet(c.options))
548 LoadOption(c.options);
549 if(configReplaces) return;
555 if((!configXplatformSet || !configReplaces) && platform && node.platforms)
557 for(p : node.platforms; !strcmpi(p.name, platformName))
559 if(skipped && p.options && OptionSet(p.options))
560 LoadOption(p.options);
565 if(skipped && node.options && OptionSet(node.options))
566 LoadOption(node.options);
567 else if(skipped && !node.parent)
575 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
576 MarkBuildTabModified();
579 ProjectConfig c = null;
580 if(!currentNode.configurations) currentNode.configurations = { };
581 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
583 currentNode.configurations.Add(c = ProjectConfig { name = CopyString(config.name) });
586 PlatformOptions p = null;
587 if(!c.platforms) c.platforms = { };
589 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
591 c.platforms.Add(p = PlatformOptions { CopyString(platformName) });
593 if(!p.options) p.options = { };
594 RetrieveOption(p.options, true);
595 if(!mergeValues) SetAttribs(1);
598 if(!c.options) c.options = { };
599 RetrieveOption(c.options, true);
600 if(!mergeValues) SetAttribs(1);
605 PlatformOptions p = null;
606 if(!currentNode.platforms) currentNode.platforms = { };
607 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
609 currentNode.platforms.Add(p = PlatformOptions { CopyString(platformName) });
611 if(!p.options) p.options = { };
612 RetrieveOption(p.options, true);
613 if(!mergeValues) SetAttribs(1);
617 if(!currentNode.options) currentNode.options = { };
618 RetrieveOption(currentNode.options, false);
619 if(!mergeValues) SetAttribs((currentNode.parent || OptionCheck(currentNode.options)) ? 1 : 0);
625 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
626 bool setAttribs = false;
627 for(node = currentNode; node; node = node.parent)
629 bool configXplatformSet = false;
630 ProjectConfig nodeConfig = null;
631 if(config && node.configurations)
633 for(c : node.configurations; !strcmpi(c.name, config.name))
635 if(platform && c.platforms)
637 for(p : c.platforms; !strcmpi(p.name, platformName))
639 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
641 LoadOption(p.options);
642 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode) ? 1 : 2); }
643 if(!mergeValues) { FinalizeLoading(); return; }
644 configXplatformSet = true;
654 if(platform && node.platforms && (!configXplatformSet || !configReplaces))
656 for(p : node.platforms; !strcmpi(p.name, platformName))
658 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
660 LoadOption(p.options);
661 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config) ? 1 : 2); }
662 if(!mergeValues) { FinalizeLoading(); return; }
668 if(nodeConfig && nodeConfig.options && ((mergeValues && !configReplaces) ? OptionCheck(nodeConfig.options) : OptionSet(nodeConfig.options)))
670 LoadOption(nodeConfig.options);
671 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !platform) ? 1 : 2); }
672 if(!mergeValues || configReplaces) { FinalizeLoading(); return; }
675 if(node.options && (mergeValues ? OptionCheck(node.options) : OptionSet(node.options)))
677 LoadOption(node.options);
678 if(!node.parent && !OptionCheck(node.options))
680 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
684 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config && !platform) ? 1 : 2); }
686 if(!mergeValues) { FinalizeLoading(); return; }
688 else if(!node.parent)
691 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
692 if(!mergeValues) { FinalizeLoading(); return; }
699 class StringOptionBox : OptionBox<String>
703 bool NotifyModified(EditBox editBox)
705 ((OptionBox)editBox.id).Retrieve();
709 textHorzScroll = true;
712 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
714 String * string = (String*)((byte *)options + option);
715 if(*string) delete *string;
716 *string = CopyString(((EditBox)editor).contents);
719 void LoadOption(ProjectOptions options)
721 ((EditBox)editor).contents = options ? *(String*)((byte *)options + option) : "";
722 ((EditBox)editor).Deselect();
725 bool OptionCheck(ProjectOptions options)
727 String string = *(String*)((byte *)options + option);
728 return string && string[0];
731 void UnsetOption(ProjectOptions options)
733 delete *(String*)((byte *)options + option);
737 class PathOptionBox : OptionBox<String>
739 bool Window::EditBoxORB(int x, int y, Modifiers mods)
741 Window parent = this.parent;
742 x += clientStart.x + position.x;
743 y += clientStart.y + position.y;
744 return ((OptionBox)this).OptionBox_OnRightButtonDown(parent, x, y, mods);
749 typeExpected = directory, browseDialog = { };
750 editBox.OnRightButtonDown = (void *)EditBoxORB;
752 bool NotifyModified(PathBox pathBox)
754 char path[MAX_LOCATION];
755 strcpy(path, pathBox.path);
756 TrimLSpaces(path, path);
757 TrimRSpaces(path, path);
759 char * chars = "*|:\",<>?";
760 char ch, * s = path, * o = path;
761 for(; (ch = *s); s++) { if(!strchr(chars, ch)) *o++ = ch; }
764 if(!fstrcmp(path, project.topNode.path))
766 else if(fstrcmp(path, ".") && !(strlen(path) > 1 && path[0] == '.' && path[1] == '.'))
767 MakePathRelative(path, project.topNode.path, path);
769 ((OptionBox)pathBox.id).Retrieve();
774 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
776 String * string = (String*)((byte *)options + option);
777 String slashPath = ((PathBox)editor).slashPath;
778 if(*string) delete *string;
779 *string = CopyString(slashPath);//(slashPath && slashPath[0]) ? CopyString(slashPath) : null;
782 void LoadOption(ProjectOptions options)
784 ((PathBox)editor).path = options ? *(String*)((byte *)options + option) : "";
785 ((PathBox)editor).Deselect();
788 bool OptionCheck(ProjectOptions options)
790 String string = *(String*)((byte *)options + option);
791 return string && string[0];
794 void UnsetOption(ProjectOptions options)
796 delete *(String*)((byte *)options + option);
800 class MultiStringOptionBox : OptionBox<Array<String>>
805 caseSensitive = true;
807 virtual Array<String> GetStrings();
808 virtual void SetStrings(Array<String> value);
810 Array<String> tempStrings;
812 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
814 Array<String> newStrings = GetStrings();
815 Array<String> * strings = (Array<String>*)((byte *)options + option);
816 if(*strings) { strings->Free(); delete *strings; }
820 Iterator<String> it { newStrings };
822 FigureOutInherited();
826 Array<String> ts = tempStrings;
831 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
832 if(found && (!configReplaces || platform)) // ADDED || platform here...
842 if(!mergeValues || (configReplaces && isCfgOrPlt && !platform))
843 *strings = newStrings;
846 *strings = (newStrings && newStrings.count) ? newStrings : null;
847 if(newStrings && !newStrings.count) delete newStrings;
853 void LoadOption(ProjectOptions options)
857 Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
865 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
866 if(!found) tempStrings.Add(s);
872 SetStrings(options ? *(Array<String>*)((byte *)options + option) : null);
876 void FinalizeLoading()
880 SetStrings(tempStrings);
885 bool OptionSet(ProjectOptions options)
887 Array<String> strings = *(Array<String>*)((byte *)options + option);
888 if(mergeValues && !configReplaces)
890 return strings && strings.count;
893 return strings != null;
896 bool OptionCheck(ProjectOptions options)
898 Array<String> strings = *(Array<String>*)((byte *)options + option);
899 return strings && strings.count;
902 void UnsetOption(ProjectOptions options)
904 Array<String> * strings = (Array<String>*)((byte *)options + option);
905 if(*strings) { strings->Free(); delete *strings; }
909 class StringArrayOptionBox : MultiStringOptionBox
911 editor = StringListBox
913 bool NotifyModified(EditBox editBox)
915 ((OptionBox)editBox.id).Retrieve();
920 // NO VIRTUAL PROPERTIES YET...
921 Array<String> GetStrings() { return ((StringListBox)editor).strings; }
922 void SetStrings(Array<String> value) { ((StringListBox)editor).strings = value; }
925 class StringsArrayOptionBox : MultiStringOptionBox
935 bool NotifyModified(StringsBox stringsBox)
937 ((OptionBox)stringsBox.id).Retrieve();
942 Array<String> GetStrings() { return ((StringsBox)editor).strings; }
943 void SetStrings(Array<String> value) { ((StringsBox)editor).strings = value; }
946 class DirsArrayOptionBox : MultiStringOptionBox
948 editor = DirectoriesBox
950 bool NotifyModified(DirectoriesBox dirsBox)
952 ((OptionBox)dirsBox.id).Retrieve();
956 bool OnChangedDir(char * * directory)
958 char fixedDirectory[MAX_LOCATION] = "";
959 if(PathCat(fixedDirectory, *directory))
961 char cwdBackup[MAX_LOCATION];
964 GetWorkingDir(cwdBackup, sizeof(cwdBackup));
965 ChangeWorkingDir(project.topNode.path);
967 FileFixCase(fixedDirectory);
969 ChangeWorkingDir(cwdBackup);
971 *directory = CopyString(fixedDirectory);
977 bool OnPrepareBrowseDir(char * * directory)
979 char dir[MAX_LOCATION];
982 GetSystemPathBuffer(dir, project.topNode.path);
984 PathCat(dir, *directory);
987 strcpy(dir, *directory);
992 *directory = CopyString(dir);
994 // GCC 4.4 bug: ----- path becomes *directory
995 //strcpy(dir, path ? path : "");
999 bool OnBrowsedDir(char * * directory)
1003 char path[MAX_LOCATION];
1004 MakePathRelative(*directory, project.topNode.path, path);
1006 *directory = CopyString(path);
1012 Array<String> GetStrings() { return ((DirectoriesBox)editor).strings; }
1013 void SetStrings(Array<String> value) { ((DirectoriesBox)editor).strings = value; }
1016 class BoolOptionBox : OptionBox<SetBool>
1022 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1024 ((OptionBox)button.id).Retrieve();
1029 bool OptionCheck(ProjectOptions options)
1031 return *(SetBool*)((byte *)options + option) == true;
1034 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1036 bool checked = ((Button)editor).checked;
1037 *(SetBool*)((byte *)options + option) = checked ? true :
1038 ((currentNode.parent || isCfgOrPlt) ? false : unset);
1041 void LoadOption(ProjectOptions options)
1043 ((Button)editor).checked = options && (*(SetBool*)((byte *)options + option) == true);
1047 class CheckBoxForEnumOptionBox : OptionBox
1053 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1055 ((OptionBox)button.id).Retrieve();
1058 for(slave = master.firstSlave; slave; slave = slave.nextSlave)
1060 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
1061 slave != (Window)button.id &&
1062 ((OptionBox)slave).option == ((OptionBox)button.id).option)
1063 ((OptionBox)slave).Load();
1071 void LoadOption(ProjectOptions options)
1073 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1074 ((Button)editor).checked = value == enumValue;
1077 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1079 Button checkBox = (Button)editor;
1080 if(checkBox.checked)
1081 *(Z*)((byte *)options + option) = enumValue;
1085 class BuildBitDepthOptionBox : CheckBoxForEnumOptionBox<BuildBitDepth> { }
1087 class DropOptionBox : OptionBox
1091 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
1093 ((OptionBox)dropBox.id).Retrieve();
1098 void LoadOption(ProjectOptions options)
1100 DropBox dropBox = (DropBox)editor;
1101 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1102 dropBox.currentRow = value ? dropBox.FindRow((int64)value) : dropBox.firstRow;
1105 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1107 DropBox dropBox = (DropBox)editor;
1108 DataRow row = dropBox.currentRow;
1109 Z value = (Z)(row ? row.tag : 0);
1110 *(Z*)((byte *)options + option) = value;
1114 class TargetTypeDB : DropOptionBox<TargetTypes>
1120 row = ((DropBox)editor).AddRow();
1121 row.tag = TargetTypes::executable;
1122 row.SetData(null, $"Executable");
1124 row = ((DropBox)editor).AddRow();
1125 row.tag = TargetTypes::sharedLibrary;
1126 row.SetData(null, $"Shared Library");
1128 row = ((DropBox)editor).AddRow();
1129 row.tag = TargetTypes::staticLibrary;
1130 row.SetData(null, $"Static Library");
1133 bool OptionCheck(ProjectOptions options)
1135 TargetTypes value = *(TargetTypes*)((byte *)options + option);
1136 return value && value != executable;
1140 class OptimizationDB : DropOptionBox<OptimizationStrategy>
1145 row = ((DropBox)editor).AddRow();
1146 row.tag = OptimizationStrategy::none;
1147 row.SetData(null, $"None");
1149 row = ((DropBox)editor).AddRow();
1150 row.tag = OptimizationStrategy::speed;
1151 row.SetData(null, $"For Speed (-O2)");
1153 row = ((DropBox)editor).AddRow();
1154 row.tag = OptimizationStrategy::size;
1155 row.SetData(null, $"For Size (-Os)");
1158 bool OptionCheck(ProjectOptions options)
1160 OptimizationStrategy value = *(OptimizationStrategy*)((byte *)options + option);
1161 return value && value != none;
1165 class WarningsDB : DropOptionBox<WarningsOption>
1170 row = ((DropBox)editor).AddRow();
1171 row.tag = WarningsOption::normal;
1172 row.SetData(null, $"Normal");
1174 row = ((DropBox)editor).AddRow();
1175 row.tag = WarningsOption::none;
1176 row.SetData(null, $"None");
1178 row = ((DropBox)editor).AddRow();
1179 row.tag = WarningsOption::all;
1180 row.SetData(null, $"All");
1183 bool OptionCheck(ProjectOptions options)
1185 WarningsOption value = *(WarningsOption*)((byte *)options + option);
1186 return value && value != none;
1190 void DrawStipple(Surface surface, Size clientSize)
1194 int x2 = clientSize.w - 1;
1195 int y2 = clientSize.h - 1;
1196 if((x2 - x1) & 1) x2--;
1197 if((y2 - y1) & 1) y2--;
1199 surface.LineStipple(0x5555);
1200 surface.Rectangle(x1, y1, x2, y2);
1201 surface.LineStipple(0);
1204 class BuildTab : Tab
1207 background = formColor;
1210 ProjectNode backupNode;
1211 String activeConfigName;
1213 ProjectNode lastSelectedNode;
1215 property char * selectedConfigName
1221 SelectorButton button = (SelectorButton)configSelector.selectedButton;
1222 if(button && button.id)
1224 ProjectConfig config = (ProjectConfig)button.id;
1232 property char * selectedPlatformName
1238 SelectorButton button = (SelectorButton)platformSelector.selectedButton;
1239 if(button && button.id)
1241 Platform platform = (Platform)button.id;
1242 char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no?
1243 return platformName;
1250 Label labelConfigurations
1252 this, anchor = { left = 8, top = 14 }, labeledWindow = configSelector;
1254 void OnRedraw(Surface surface)
1256 Label::OnRedraw(surface);
1257 if(labeledWindow.active) DrawStipple(surface, clientSize);
1260 SelectorBar configSelector
1262 this, text = $"Configurations: ", anchor = { left = 98, top = 8, right = 54 }; size = { 0, 26 };
1264 direction = horizontal, scrollable = true;
1266 bool OnKeyDown(Key key, unichar ch)
1270 ((BuildTab)parent).createConfig.NotifyClicked(parent, ((BuildTab)parent).createConfig, 0, 0, 0);
1275 ((BuildTab)parent).deleteConfig.NotifyClicked(parent, ((BuildTab)parent).deleteConfig, 0, 0, 0);
1278 return SelectorBar::OnKeyDown(key, ch);
1281 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1283 ((BuildTab)master).labelConfigurations.Update(null);
1290 parent = this, bevelOver = true, inactive = true;
1292 anchor = { top = 10, right = 31 };
1293 hotKey = altC, bitmap = BitmapResource { fileName = ":actions/docNew.png", alphaBlend = true };
1295 bool NotifyClicked(Button b, int x, int y, Modifiers mods)
1297 char tmp[MAX_F_STRING];
1298 ProjectConfig config;
1299 EditableSelectorButton button;
1301 FindUniqueConfigName("NewConfig", false, tmp);
1305 makingModified = true;
1306 compilingModified = true;
1307 linkingModified = true;
1308 name = CopyString(tmp);
1311 // objectsDirectory = /*CopyString(*/defaultObjDirExpression/*)*/;
1314 if(!project.topNode.configurations) project.topNode.configurations = { };
1315 project.topNode.configurations.Add(config);
1317 targetType = project.config.options.targetType;
1319 config.options.targetFileName = project.moduleName;
1320 config.options.targetDir.dir = "";
1321 config.options.objectsDirectory = defaultObjDirExpression);
1322 config.options.debug = true;
1323 config.options.optimization = none;
1324 config.options.warnings = all;
1329 configSelector, renameable = true, master = this, text = config.name, id = (int64)config;
1330 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1333 configSelector.Select(button);
1334 modifiedDocument = true;
1338 /*Button duplicateConfig
1340 parent = this, bevelOver = true, inactive = true;
1342 anchor = { top = 10, right = 31 };
1343 hotKey = altU, bitmap = BitmapResource { fileName = ":actions/editCopy.png", alphaBlend = true };
1347 parent = this, bevelOver = true, inactive = true;
1349 anchor = { top = 10, right = 8 };
1350 hotKey = altD, bitmap = BitmapResource { fileName = ":actions/delete2.png", alphaBlend = true };
1352 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1356 String title = PrintString($"Delete ", config.name, $" Configuration");
1357 String msg = PrintString($"Are you sure you wish to delete the ", config.name, $" configuration?");
1358 if(MessageBox { type = okCancel, text = title, contents = msg }.Modal() == ok)
1360 Iterator<Window> it { configSelector.controls };
1361 ProjectConfig configToDelete = config;
1365 SelectorButton button = (SelectorButton)it.data;
1366 if((ProjectConfig)button.id == config)
1368 button.visible = false;
1373 button = (SelectorButton)it.data;
1374 config = (ProjectConfig)button.id;
1375 configSelector.Select(button);
1381 SelectorButton button = configSelector.FindButtonByID((int64)configToDelete);
1383 configSelector.RemoveButton(button);
1385 project.topNode.DeleteConfig(configToDelete);
1387 modifiedDocument = true;
1396 Label labelPlatforms
1398 this, anchor = { left = 8, top = 44 }, labeledWindow = platformSelector;
1400 void OnRedraw(Surface surface)
1402 Label::OnRedraw(surface);
1403 if(labeledWindow.active) DrawStipple(surface, clientSize);
1406 SelectorBar platformSelector
1408 this, text = $"Platforms: ", anchor = { left = 64, top = 38, right = 54 }; size = { 0, 26 };
1410 direction = horizontal, scrollable = true;
1412 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1414 ((BuildTab)master).labelPlatforms.Update(null);
1419 TabControl buildTabControl
1421 this, background = formColor, anchor = { left = 8, top = 64, right = 8, bottom = 8 };
1422 curTab = compilerTab;
1424 CompilerTab compilerTab { this, tabControl = buildTabControl };
1425 LinkerTab linkerTab { this, tabControl = buildTabControl };
1426 BuilderTab builderTab { this, tabControl = buildTabControl };
1429 this, font = { font.faceName, font.size, italic = true }, stayOnTop = true,
1430 text = $"(Right click or press Ctrl-Del to revert an option to inherited value)", anchor = { top = 72, right = 16 }
1433 void FindUniqueConfigName(char * baseName, bool startWithNumber, char * output)
1436 char tmp[MAX_F_STRING];
1438 sprintf(tmp, "%s%d", baseName, num);
1440 strcpy(tmp, baseName);
1443 ProjectConfig config = null;
1444 for(c : project.topNode.configurations)
1445 { // TOFIX: Error when omitting these brackets, c not found
1446 if(c.name && !strcmp(c.name, tmp))
1455 sprintf(tmp, "%s%d", baseName, num);
1460 strcpy(output, tmp);
1463 bool PlatformClicked(Button clickedButton, int x, int y, Modifiers mods)
1465 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1467 platform = (Platform)clickedButton.id;
1469 // Load Settings Into Dialog
1470 compilerTab.LoadSettings();
1471 linkerTab.LoadSettings();
1472 builderTab.LoadSettings();
1475 buildTabControl.Activate();
1477 if(compilerTab.rightPaneHeader.visible)
1478 compilerTab.rightPaneHeader.Update(null);
1479 ((ProjectSettings)master).UpdateDialogTitle();
1486 platformSelector.DestroyChildren();
1487 configSelector.DestroyChildren();
1489 delete activeConfigName;
1492 bool ConfigOnRename(EditableSelectorButton button, char * * oldName, char * * newName)
1497 for(c = 0; (ch = (*newName)[c]); c++)
1499 if(ch == '_' || isalpha(ch) || (isdigit(ch) && d))
1500 (*newName)[d++] = ch;
1506 for(c : project.topNode.configurations; c != config)
1508 if(!strcmpi(c.name, *newName))
1514 if(found || !(*newName)[0])
1516 char tmp[MAX_F_STRING];
1517 char * tmpName = config.name;
1519 FindUniqueConfigName("NewConfig", false, tmp);
1520 config.name = tmpName;
1522 *newName = CopyString(tmp);
1526 if(activeConfigName && !strcmp(activeConfigName, *oldName))
1528 delete activeConfigName;
1529 activeConfigName = CopyString(*newName);
1532 project.topNode.RenameConfig(config.name, *newName);
1534 modifiedDocument = true;
1538 bool ConfigClicked(Button clickedButton, int x, int y, Modifiers mods)
1540 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1542 config = (ProjectConfig)clickedButton.id;
1544 // Load Settings Into Dialog
1545 compilerTab.LoadSettings();
1546 linkerTab.LoadSettings();
1547 builderTab.LoadSettings();
1549 deleteConfig.disabled = (clickedButton._class == class(SelectorButton));
1552 buildTabControl.Activate();
1554 compilerTab.fileList.Update(null);
1555 if(compilerTab.rightPaneHeader.visible)
1556 compilerTab.rightPaneHeader.Update(null);
1557 ((ProjectSettings)master).UpdateDialogTitle();
1562 void SelectNode(ProjectNode node, bool ignoreAsLastSelection)
1564 if(node != currentNode)
1566 Window ac = compilerTab.rightPane.activeChild;
1567 bool prevNodeRes = currentNode ? currentNode.isInResources : false;
1570 if(!node) node = project.topNode;
1572 newNodeRes = node.isInResources;
1575 if(!ignoreAsLastSelection)
1576 lastSelectedNode = node;
1578 ((ProjectSettings)master).UpdateDialogTitle();
1579 if(node.type == project)
1581 compilerTab.rightPaneHeader.visible = false;
1585 compilerTab.rightPaneHeader.id = (int64)node;
1586 compilerTab.rightPaneHeader.Update(null);
1587 compilerTab.rightPaneHeader.visible = true;
1591 DataRow row = compilerTab.fileList.FindSubRow((int64)currentNode);
1594 compilerTab.fileList.currentRow = row;
1595 while((row = row.parent))
1596 row.collapsed = false;
1600 if(prevNodeRes != newNodeRes)
1602 compilerTab.labelObjDir.visible = !newNodeRes;
1603 compilerTab.objDir.visible = !newNodeRes;
1604 compilerTab.excludeFromBuild.visible = !newNodeRes;
1605 compilerTab.labelPreprocessorDefs.visible = !newNodeRes;
1606 compilerTab.preprocessorDefs.visible = !newNodeRes;
1607 compilerTab.labelDefaultNameSpace.visible = !newNodeRes;
1608 compilerTab.defaultNameSpace.visible = !newNodeRes;
1609 compilerTab.strictNameSpaces.visible = !newNodeRes;
1610 compilerTab.memoryGuard.visible = !newNodeRes;
1611 compilerTab.noLineNumbers.visible = !newNodeRes;
1612 compilerTab.debug.visible = !newNodeRes;
1613 compilerTab.labelWarnings.visible = !newNodeRes;
1614 compilerTab.warnings.visible = !newNodeRes;
1615 compilerTab.profiling.visible = !newNodeRes;
1616 compilerTab.labelOptimization.visible = !newNodeRes;
1617 compilerTab.optimization.visible = !newNodeRes;
1618 compilerTab.fastMath.visible = !newNodeRes;
1619 compilerTab.labelIncludeDirs.visible = !newNodeRes;
1620 compilerTab.includeDirs.visible = !newNodeRes;
1623 if(node == project.topNode)
1625 compilerTab.objDir.visible = true;
1626 compilerTab.labelObjDir.visible = true;
1628 compilerTab.excludeFromBuild.visible = false;
1632 compilerTab.objDir.visible = false;
1633 compilerTab.labelObjDir.visible = false;
1635 compilerTab.excludeFromBuild.visible = (node != project.resNode);
1638 // Load Settings Into Dialog
1639 compilerTab.LoadSettings();
1640 linkerTab.LoadSettings();
1641 builderTab.LoadSettings();
1647 if(ac == compilerTab.excludeFromBuild.editor)
1648 ac = compilerTab.objDir.editor;
1649 else if(compilerTab.excludeFromBuild.editor.visible)
1650 ac = compilerTab.excludeFromBuild.editor;
1657 void CreateConfigButtons()
1659 SelectorButton commonButton;
1661 // Create Config Buttons
1662 commonButton = SelectorButton
1664 configSelector, master = this, text = $"Common", id = (int64)null; font = { font.faceName, font.size, true };
1666 NotifyClicked = ConfigClicked;
1671 if(project.topNode.configurations)
1673 for(c : project.topNode.configurations)
1675 EditableSelectorButton button
1677 configSelector, master = this, renameable = true, text = c.name, id = (int64)c;
1678 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1687 SelectorButton button;
1689 activeConfigName = project.config ? CopyString(project.config.name) : null;
1691 compilerTab.AddNode(project.topNode, null);
1693 CreateConfigButtons();
1695 platformButton = button =
1697 platformSelector, master = this, text = $"Common", id = 0; font = { font.faceName, font.size, true };
1698 NotifyClicked = PlatformClicked; checked = true;
1703 for(p = (Platform)1; p < Platform::enumSize; p++)
1705 SelectorButton button
1707 platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p;
1708 NotifyClicked = PlatformClicked;
1712 SelectorButton platformButton;
1716 // Backup Current Settings
1717 backupNode = project.topNode.Backup();
1719 buildTabControl.Activate();
1722 Iterator<Window> it { configSelector.controls };
1725 SelectorButton configButton = (SelectorButton)it.data;
1726 ProjectConfig buttonConfig = (ProjectConfig)configButton.id;
1727 if(buttonConfig == project.config)
1729 configButton.Activate();
1730 configButton.checked = true;
1731 ConfigClicked(configButton, 0, 0, (Modifiers)null);
1738 platformButton.MakeActive();
1739 platformButton = null;
1748 lastSelectedNode = null;
1750 project.config = null;
1752 /* // THIS IS NOW AUTOMATED WITH A project CHECK IN ProjectNode
1753 project.configurations = project.topNode.configurations;
1754 project.platforms = project.topNode.platforms;
1755 project.options = project.topNode.options;
1758 if(project.topNode.configurations)
1760 for(c : project.topNode.configurations)
1762 if(!strcmpi(c.name, activeConfigName))
1771 List<ProjectConfig> configs = project.topNode.configurations;
1772 if(configs && configs.count)
1773 project.config = configs[0];
1776 ide.UpdateToolBarActiveConfigs(false);
1779 void RevertChanges()
1781 String configName = config ? CopyString(config.name) : null;
1783 // Revert to saved project options
1784 project.topNode.Revert(backupNode);
1786 configSelector.DestroyChildren();
1787 CreateConfigButtons();
1789 // Reselect Configuration
1792 Iterator<Window> it { configSelector.controls };
1795 Button button = (Button)it.data;
1796 ProjectConfig c = (ProjectConfig)button.id;
1797 if(c && !strcmp(c.name, configName))
1801 button.checked = true;
1802 ConfigClicked(button, 0,0, 0);
1808 SelectNode(project.topNode, false);
1813 bool OnClose(bool parentClosing)
1815 if(modifiedDocument)
1817 DialogResult diagRes = MessageBox
1819 type = yesNoCancel, master = ide,
1820 text = $"Save changes to project settings?",
1821 contents = $"Would you like to save changes made to the build options?"
1825 if(diagRes == cancel)
1829 project.MarkChanges(backupNode);
1830 project.topNode.modified = true;
1831 ide.projectView.modifiedDocument = true;
1832 ide.UpdateToolBarActiveConfigs(false);
1833 ide.projectView.Update(null);
1835 modifiedDocument = false;
1841 class CompilerTab : Tab
1843 background = formColor;
1846 Window leftPane { this, size = { 180 }, anchor = { left = 0, top = 0, bottom = 0 }, background = formColor };
1848 Label labelFileList { leftPane, this, position = { 8, 8 }, labeledWindow = fileList };
1851 leftPane, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
1852 // THIS WOULD BE EVEN MORE FUN: multiSelect = true,
1853 fullRowSelect = false, collapseControl = true, treeBranches = true;
1854 alwaysHighLight = true;
1855 selectionColor = unfocusedSelectorColor;
1857 anchor = Anchor { left = 8, top = 24, right = 4, bottom = 8 };
1860 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1862 BuildTab buildTab = (BuildTab)master;
1863 ProjectNode node = (ProjectNode)row.tag;
1864 buildTab.SelectNode(node, false);
1868 void OnRedraw(Surface surface)
1870 ide.projectView.drawingInProjectSettingsDialog = true;
1871 ListBox::OnRedraw(surface);
1872 ide.projectView.drawingInProjectSettingsDialog = false;
1875 bool NotifyActivate(Window window, bool active, Window previous)
1879 //subclass(Skin) skinClass = (subclass(Skin))eSystem_FindClass(app, app.skin);
1880 fileList.selectionColor = Color { 10, 36, 106 }; //skinClass.selectionColor; // darkBlue;
1882 else if(fileList.currentRow)
1884 DataRow currentRow = fileList.currentRow;
1885 //int headerSize = ((fileList.style.header) ? fileList.rowHeight : 0);
1886 int height = fileList.clientSize.h + 1;// - fileList.headerSize;
1887 fileList.selectionColor = unfocusedSelectorColor;
1888 if(currentRow && currentRow.index * fileList.rowHeight > fileList.scroll.y + height - fileList.rowHeight)
1889 fileList.SetScrollPosition(fileList.scroll.x, currentRow.index * fileList.rowHeight - height + fileList.rowHeight);
1890 else if(!currentRow || currentRow.index * fileList.rowHeight < fileList.scroll.y)
1891 fileList.SetScrollPosition(fileList.scroll.x, currentRow ? currentRow.index * fileList.rowHeight : 0);
1901 this, anchor = { left = 196, top = 0, right = 0, bottom = 0 }, background = formColor, tabCycle = true;
1904 Window rightPaneHeader
1906 rightPane, this, size = { h = 21 }, anchor = { left = 0, top = 0, right = 0 }, background = Color { 70, 96, 166 };//0x0F3F66;
1907 foreground = white; visible = false;
1909 void OnRedraw(Surface surface)
1913 ide.projectView.drawingInProjectSettingsDialogHeader = true;
1914 ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(ProjectNode)._vTbl[__ecereVMethodID_class_OnDisplay])(class(ProjectNode),
1915 (void *)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
1916 ide.projectView.drawingInProjectSettingsDialogHeader = false;
1921 PaneSplitter splitter
1923 this, leftPane = leftPane, rightPane = rightPane, split = 188
1926 Label labelObjDir { rightPane, this, position = { 8, 8 }, labeledWindow = objDir };
1927 PathOptionBox objDir
1929 rightPane, this, size = { 250, 22 }, anchor = { left = 8, top = 24, right = 8 };
1930 text = $"Intermediate Objects Directory", hotKey = altJ, option = OPTION(objectsDirectory);
1933 BoolOptionBox excludeFromBuild
1935 rightPane, this, position = { 8, 28 },
1936 text = $"Exclude from Build", visible = false, option = OPTION(excludeFromBuild);
1939 Label labelPreprocessorDefs { rightPane, this, position = { 8, 50 }, labeledWindow = preprocessorDefs };
1940 StringArrayOptionBox preprocessorDefs
1942 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
1943 text = $"Preprocessor Definitions", hotKey = altD, option = OPTION(preprocessorDefinitions);
1946 Label labelDefaultNameSpace { rightPane, this, position = { 8, 92 }, labeledWindow = defaultNameSpace };
1947 StringOptionBox defaultNameSpace
1949 rightPane, this, size = { 160, 22 }, position = { 8, 108 };
1950 text = $"Default Name Space", option = OPTION(defaultNameSpace);
1952 BoolOptionBox strictNameSpaces
1954 rightPane, this, position = { 172, 112 },
1955 text = $"Strict Name Spaces", option = OPTION(strictNameSpaces);
1958 BoolOptionBox fastMath
1960 rightPane, this, position = { 316, 112 },
1961 text = $"Fast Math", option = OPTION(fastMath);
1964 BoolOptionBox memoryGuard
1966 rightPane, this, position = { 8, 154 };
1967 text = $"MemoryGuard", hotKey = altM, option = OPTION(memoryGuard);
1970 Label labelWarnings { rightPane, position = { 116, 138 }, labeledWindow = warnings };
1973 rightPane, this, position = { 116, 154 };
1974 text = $"Warnings", hotKey = altW, option = OPTION(warnings);
1977 Label labelOptimization { rightPane, position = { 220, 138 }, labeledWindow = optimization };
1978 OptimizationDB optimization
1980 rightPane, this, position = { 220, 154 }, size = { 120, 22 };
1981 text = $"Optimization", hotKey = altO, option = OPTION(optimization);
1986 rightPane, this, position = { 8, 188 };
1987 text = $"Debuggable", hotKey = altG, option = OPTION(debug);
1990 BoolOptionBox profiling
1992 rightPane, this, position = { 116, 188 };
1993 text = $"Profiling Data", hotKey = altP, option = OPTION(profile);
1996 BoolOptionBox noLineNumbers
1998 rightPane, this, position = { 220, 188 };
1999 text = $"No Line Numbers", hotKey = altN, option = OPTION(noLineNumbers);
2002 Label labelCompilerOptions { rightPane, this, position = { 8, 208 }, labeledWindow = compilerOptions };
2003 StringArrayOptionBox compilerOptions
2005 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 224, right = 8 };
2006 text = $"Compiler Options", hotKey = altO, option = OPTION(compilerOptions);
2007 configReplaces = true;
2010 Label labelIncludeDirs { includeDirs.editor, labeledWindow = includeDirs, position = { 0, 6 }; };
2011 DirsArrayOptionBox includeDirs
2013 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 250, right = 8, bottom = 8 };
2014 text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs);
2019 fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false,
2020 userData = null /* Now set in the ProjectNode directly to know we're in ProjectSettings Dialog -- ide.projectView*/ });
2025 BuildTab buildTab = (BuildTab)master;
2026 buildTab.SelectNode(buildTab.lastSelectedNode, true);
2030 void AddNode(ProjectNode node, DataRow addTo)
2032 DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
2034 row.tag = (int64)node;
2036 row.SetData(null, node);
2038 if(node.files && node.files.first && node.parent &&
2039 !(!node.parent.parent &&
2040 (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") ||
2041 !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
2042 row.collapsed = true;
2043 else if(node.type == folder)
2044 node.icon = openFolder;
2048 for(child : node.files)
2049 AddNode(child, row);
2056 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2057 if(eClass_IsDerived(ob._class, class(OptionBox)))
2060 if(activeChild && activeChild.active)
2062 Window control = activeChild;
2063 control.Deactivate();
2070 objDir.editor.Activate();
2075 class LinkerTab : Tab
2077 background = formColor;
2080 Label labelTargetName { this, position = { 8, 8 }, labeledWindow = targetName };
2081 StringOptionBox targetName
2083 this, position = { 8, 24 }, size = { 200, 22 };
2084 text = $"Target Name", hotKey = altN, option = OPTION(targetFileName);
2087 Label labelTargetType { this, position = { 216, 8 }, labeledWindow = targetType };
2088 TargetTypeDB targetType
2090 this, position = { 216, 24 }, size = { 120, 22 };
2091 text = $"Target Type", hotKey = altT, option = OPTION(targetType);
2094 Label labelTargetDirectory { this, position = { 344, 8 }, labeledWindow = targetDirectory };
2095 PathOptionBox targetDirectory
2097 this, size = { 270, 22 }, anchor = { left = 344, top = 24, right = 8 };
2098 hotKey = altR, text = $"Target Directory", option = OPTION(targetDirectory);
2101 Label labelLibraries { this, position = { 8, 50 }, labeledWindow = libraries };
2102 StringArrayOptionBox libraries
2104 this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
2105 text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries);
2106 configReplaces = true;
2109 Label labelLinkerOptions { this, position = { 8, 92 }, labeledWindow = linkerOptions };
2110 StringArrayOptionBox linkerOptions
2112 this, size = { 290, 22 }, anchor = { left = 8, top = 108, right = 8 };
2113 text = $"Linker Options", hotKey = altO, option = OPTION(linkerOptions);
2114 configReplaces = true;
2117 BoolOptionBox console
2119 this, position = { 8, 138 };
2120 text = $"Console Application", hotKey = altC, option = OPTION(console);
2123 BoolOptionBox compress
2125 this, position = { 8, 162 };
2126 text = $"Compress", hotKey = altW, option = OPTION(compress);
2129 Label labelLibraryDirs { libraryDirs.editor, labeledWindow = libraryDirs, position = { 0, 6 }; };
2130 DirsArrayOptionBox libraryDirs
2132 this, size = { 290, 22 }, anchor = { left = 8, top = 182, right = 8, bottom = 8 };
2133 text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs);
2138 ((BuildTab)master).SelectNode(project.topNode, true);
2145 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2146 if(eClass_IsDerived(ob._class, class(OptionBox)))
2148 compress.disabled = (config && config.options && config.options.debug == true) || project.topNode.options.debug == true;
2150 if(activeChild && activeChild.active)
2152 Window control = activeChild;
2153 control.Deactivate();
2159 class BuilderTab : Tab
2161 background = formColor;
2164 Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
2165 StringsArrayOptionBox prebuildCommands
2167 this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
2168 text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
2171 Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
2172 StringsArrayOptionBox postbuildCommands
2174 this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
2175 text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
2180 bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
2182 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2183 if(eClass_IsDerived(ob._class, class(OptionBox)))
2186 if(activeChild && activeChild.active)
2188 Window control = activeChild;
2189 control.Deactivate();