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
34 bool quoted = strchr(item, ' ') != null;
48 Array<String> array { };
50 char * contents = property::contents;
54 for(c = 0; (ch = contents[c]); c++)
56 if(ch == ' ' && !quoted)
59 array.Add(MakeString(contents + start, c - start));
67 array.Add(MakeString(contents + start, c - start));
79 array.Add(MakeString(contents + start, c - start));
85 define dialogTitle = $"Project Settings";
86 static Color unfocusedSelectorColor { 70, 96, 166 };
87 class ProjectSettings : Window
90 background = formColor;
91 borderStyle = sizable;
92 minClientSize = { 650, 490 };
97 property Project project
102 projectTab.project = value;
105 buildTab.SelectNode(project.topNode, false);
107 if(project && project.topNode && project.topNode.name && project.topNode.name[0])
110 get { return ::project; }
113 property ProjectNode projectNode
115 set { buildTab.SelectNode(value, false); }
116 get { return currentNode; }
119 void UpdateDialogTitle()
121 //char * s = PrintString("Project Settings - ", project.topNode.fileName);
123 char * projectName = new char[strlen(project.topNode.name) + 1];
124 char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
125 char * config = buildTab.selectedConfigName;
126 char * platform = buildTab.selectedPlatformName;
127 char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 +
128 strlen(nodeName) + 2 + strlen(config) + 1 + strlen(platform) + 1 + 1];
129 strcpy(label, dialogTitle);
130 strcat(label, " - ");
131 strcpy(projectName, project.topNode.name);
132 StripExtension(projectName);
133 strcat(label, projectName);
134 if(currentNode && currentNode.type != project)
136 strcat(label, " - ");
137 strcat(label, nodeName);
139 if(strlen(config) || strlen(platform))
143 strcat(label, config);
144 if(strlen(config) && strlen(platform))
147 strcat(label, platform);
160 TabControl prjTabControl
162 this, background = formColor, anchor = { left = 8, top = 4, right = 8, bottom = 38 };
164 ProjectTab projectTab { this, tabControl = prjTabControl };
165 BuildTab buildTab { this, tabControl = prjTabControl };
166 WorkspaceTab workspaceTab { this, tabControl = prjTabControl };
170 this, size = { 80, 22 };
171 anchor = { right = 8, bottom = 8 };
172 text = $"Cancel", hotKey = escape, id = DialogResult::cancel;
174 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
176 if(prjTabControl.curTab.modifiedDocument)
178 DialogResult diagRes = MessageBox
180 type = okCancel, master = ide,
181 text = $"Lose Changes?",
182 contents = $"Are you sure you wish to discard changes made to the build options?"
186 if(prjTabControl.curTab == buildTab)
188 buildTab.RevertChanges();
189 buildTab.modifiedDocument = false;
191 if(prjTabControl.curTab == workspaceTab)
193 workspaceTab.modifiedDocument = false;
195 if(prjTabControl.curTab == projectTab)
197 projectTab.modifiedDocument = false;
199 Destroy(DialogResult::cancel);
203 Destroy(DialogResult::cancel);
209 this, size = { 80, 22 };
210 anchor = { right = 96, bottom = 8 };
211 text = $"OK", isDefault = true;
213 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
215 if(prjTabControl.curTab == buildTab && buildTab.modifiedDocument)
217 buildTab.modifiedDocument = false;
219 project.topNode.modified = true;
220 project.MarkChanges(buildTab.backupNode);
221 ide.projectView.modifiedDocument = true;
222 ide.UpdateToolBarActiveConfigs(false);
223 ide.projectView.Update(null);
225 if(prjTabControl.curTab == workspaceTab && workspaceTab.modifiedDocument)
227 workspaceTab.SaveChanges();
228 workspaceTab.modifiedDocument = false;
230 if(prjTabControl.curTab == projectTab && projectTab.modifiedDocument)
232 projectTab.SaveChanges();
233 projectTab.modifiedDocument = false;
235 Destroy(DialogResult::ok);
243 prjTabControl.curTab = buildTab;
248 #define OPTION(x) ((uint)(&((ProjectOptions)0).x))
250 // TOFIX: USING T INSTEAD OF Z HERE CAUSED US SOME CONFLICTS WITH T IN Array TEMPLATES
252 // the BlendFileConfigPlatformProjectOptions function and the GenericOptionTools class
253 // contain code that is closely matched to the following code
254 // output changing modification should be mirrored in both implementations
255 class OptionBox<class Z> : CommonControl
257 bool mergeValues, configReplaces;
266 property Window editor
272 editor.OnRightButtonDown = OptionBox_OnRightButtonDown;
273 chainKeyDown = (void *)editor.OnKeyDown;
274 editor.OnKeyDown = OptionBox_OnKeyDown;
278 property bool visible { set { editor.visible = value; } get { return editor.visible; } }
279 property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)this; } }
280 property Point position { set { editor.position = value; } }
281 property Size size { set { editor.size = value; } }
282 property Anchor anchor { set { editor.anchor = value; } }
283 property Key hotKey { set { editor.hotKey = value; } }
284 property char * text { set { editor.text = value; Window::text = value; } }
294 bool NotifySelect(MenuItem selection, Modifiers mods)
296 OptionBox ob = (OptionBox)id;
297 if(eClass_IsDerived(ob._class, class(CheckBoxForEnumOptionBox)))
300 for(slave = ob.master.firstSlave; slave; slave = slave.nextSlave)
302 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
303 ((OptionBox)slave).option == ob.option)
304 ((OptionBox)slave).Unset();
313 bool Window::OptionBox_OnRightButtonDown(int x, int y, Modifiers mods)
315 OptionBox ob = (OptionBox)id;
316 GuiApplication app = ((GuiApplication)__thisModule.application);
318 PopupMenu { null, this, menu = ob.clearMenu,
319 position = { absPosition.x + clientStart.x + x - app.desktop.position.x, absPosition.y + clientStart.y + y - app.desktop.position.y } }.Create();
323 bool Window::OptionBox_OnKeyDown(Key key, unichar ch)
325 OptionBox ob = (OptionBox)id;
326 if(key == Key { del, ctrl = true } || key == Key { keyPadDelete, ctrl = true })
331 return (((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
334 // code: 0 = not set anywhere, 1 = overridden here, 2 = inherited
335 void SetAttribs(int code)
340 for(c = Window::parent.firstChild; c; c = c.next)
342 if(eClass_IsDerived(c._class, class(Label)))
345 if(label.labeledWindow == this)
353 for(c = editor.firstChild; c; c = c.next)
355 if(eClass_IsDerived(c._class, class(Label)))
362 // control.foreground = foreground;
364 if(code == 0 || code == 1)
366 editor.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
367 editor.background = white;
371 Color foreground = 0x0F3F66;
372 int r = foreground.r, g = foreground.g, b = foreground.b;
376 editor.font = { editor.font.faceName, editor.font.size };
378 r = (int)(alpha * r + src.r * (1 - alpha));
379 g = (int)(alpha * g + src.g * (1 - alpha));
380 b = (int)(alpha * b + src.b * (1 - alpha));
382 r = Max(0,Min(255,r));
383 g = Max(0,Min(255,g));
384 b = Max(0,Min(255,b));
386 editor.background = Color { (byte) r, (byte) g, (byte) b };
391 label.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
392 //label.foreground = foreground;
396 virtual void FinalizeLoading();
398 virtual void LoadOption(ProjectOptions options);
399 virtual void RetrieveOption(ProjectOptions options, bool isCfgOrPlt);
400 virtual void UnsetOption(ProjectOptions options)
403 *(Z*)((byte *)options + option) = value;
406 virtual bool OptionSet(ProjectOptions options)
408 // TOFIX: If you get a crash here, it might be because JSON.ec must be after ProjectConfig.ec in the project files
409 // JSON.ec must also be before ProjectSettings.ec in the project files
410 if(*(Z*)((byte *)options + option))
414 // BUG: OptionCheck = OptionSet; // Overrides derived classes OptionCheck ?
416 virtual bool OptionCheck(ProjectOptions options)
418 return OptionSet(options);
421 void MarkBuildTabModified()
423 BuildTab buildTab = (BuildTab)master;
424 while(buildTab && buildTab._class != class(BuildTab))
425 buildTab = (BuildTab)buildTab.master;
426 if(buildTab) buildTab.modifiedDocument = true;
431 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
432 MarkBuildTabModified();
436 ProjectConfig c = null;
437 if(currentNode.configurations)
439 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
444 PlatformOptions p = null;
447 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
450 if(p.options && OptionSet(p.options))
451 UnsetOption(p.options);
452 if(p.options && p.options.isEmpty)
456 Iterator<PlatformOptions> it { c.platforms };
464 if(!c.platforms.count)
470 if(c.options && OptionSet(c.options))
471 UnsetOption(c.options);
472 if(c.options && c.options.isEmpty)
475 // DON'T DELETE PROJECT CONFIGS HERE!
476 if(!c.options && currentNode != project.topNode)
478 Iterator<ProjectConfig> it { currentNode.configurations };
486 if(!currentNode.configurations.count)
487 currentNode.configurations = null;
494 PlatformOptions p = null;
495 if(currentNode.platforms)
497 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
500 if(p.options && OptionSet(p.options))
501 UnsetOption(p.options);
502 if(p.options && p.options.isEmpty)
506 Iterator<PlatformOptions> it { currentNode.platforms };
514 if(!currentNode.platforms.count)
515 currentNode.platforms = null;
521 if(currentNode.options && OptionSet(currentNode.options))
522 UnsetOption(currentNode.options);
523 if(currentNode.options && currentNode.options.isEmpty)
525 // delete currentNode.options;
526 // Property will free:
527 currentNode.options = null;
533 void FigureOutInherited()
536 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
537 bool skipped = false;
538 for(node = currentNode; node; node = node.parent)
540 bool configXplatformSet = false;
541 if(config && node.configurations)
543 for(c : node.configurations; !strcmpi(c.name, config.name))
545 if(platform && c.platforms)
547 for(p : c.platforms; !strcmpi(p.name, platformName))
549 if(p.options && OptionSet(p.options))
552 LoadOption(p.options);
554 configXplatformSet = true;
560 if(skipped && c.options && OptionSet(c.options))
562 LoadOption(c.options);
563 if(configReplaces) return;
569 if((!configXplatformSet || !configReplaces) && platform && node.platforms)
571 for(p : node.platforms; !strcmpi(p.name, platformName))
573 if(skipped && p.options && OptionSet(p.options))
574 LoadOption(p.options);
579 if(skipped && node.options && OptionSet(node.options))
580 LoadOption(node.options);
581 else if(skipped && !node.parent)
589 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
590 MarkBuildTabModified();
593 ProjectConfig c = null;
594 if(!currentNode.configurations) currentNode.configurations = { };
595 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
597 currentNode.configurations.Add(c = ProjectConfig { name = CopyString(config.name) });
600 PlatformOptions p = null;
601 if(!c.platforms) c.platforms = { };
603 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
605 c.platforms.Add(p = PlatformOptions { CopyString(platformName) });
607 if(!p.options) p.options = { };
608 RetrieveOption(p.options, true);
609 if(!mergeValues) SetAttribs(1);
612 if(!c.options) c.options = { };
613 RetrieveOption(c.options, true);
614 if(!mergeValues) SetAttribs(1);
619 PlatformOptions p = null;
620 if(!currentNode.platforms) currentNode.platforms = { };
621 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
623 currentNode.platforms.Add(p = PlatformOptions { CopyString(platformName) });
625 if(!p.options) p.options = { };
626 RetrieveOption(p.options, true);
627 if(!mergeValues) SetAttribs(1);
631 if(!currentNode.options) currentNode.options = { };
632 RetrieveOption(currentNode.options, false);
633 if(!mergeValues) SetAttribs((currentNode.parent || OptionCheck(currentNode.options)) ? 1 : 0);
639 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
640 bool setAttribs = false;
641 for(node = currentNode; node; node = node.parent)
643 bool configXplatformSet = false;
644 ProjectConfig nodeConfig = null;
645 if(config && node.configurations)
647 for(c : node.configurations; !strcmpi(c.name, config.name))
649 if(platform && c.platforms)
651 for(p : c.platforms; !strcmpi(p.name, platformName))
653 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
655 LoadOption(p.options);
656 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode) ? 1 : 2); }
657 if(!mergeValues) { FinalizeLoading(); return; }
658 configXplatformSet = true;
668 if(platform && node.platforms && (!configXplatformSet || !configReplaces))
670 for(p : node.platforms; !strcmpi(p.name, platformName))
672 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
674 LoadOption(p.options);
675 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config) ? 1 : 2); }
676 if(!mergeValues) { FinalizeLoading(); return; }
682 if(nodeConfig && nodeConfig.options && ((mergeValues && !configReplaces) ? OptionCheck(nodeConfig.options) : OptionSet(nodeConfig.options)))
684 LoadOption(nodeConfig.options);
685 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !platform) ? 1 : 2); }
686 if(!mergeValues || configReplaces) { FinalizeLoading(); return; }
689 if(node.options && (mergeValues ? OptionCheck(node.options) : OptionSet(node.options)))
691 LoadOption(node.options);
692 if(!node.parent && !OptionCheck(node.options))
694 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
698 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config && !platform) ? 1 : 2); }
700 if(!mergeValues) { FinalizeLoading(); return; }
702 else if(!node.parent)
705 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
706 if(!mergeValues) { FinalizeLoading(); return; }
713 class StringOptionBox : OptionBox<String>
717 bool NotifyModified(EditBox editBox)
719 ((OptionBox)editBox.id).Retrieve();
723 textHorzScroll = true;
726 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
728 String * string = (String*)((byte *)options + option);
729 if(*string) delete *string;
730 *string = CopyString(((EditBox)editor).contents);
733 void LoadOption(ProjectOptions options)
735 ((EditBox)editor).contents = options ? *(String*)((byte *)options + option) : "";
736 ((EditBox)editor).Deselect();
739 bool OptionCheck(ProjectOptions options)
741 String string = *(String*)((byte *)options + option);
742 return string && string[0];
745 void UnsetOption(ProjectOptions options)
747 delete *(String*)((byte *)options + option);
751 class PathOptionBox : OptionBox<String>
753 bool Window::EditBoxORB(int x, int y, Modifiers mods)
755 Window parent = this.parent;
756 x += clientStart.x + position.x;
757 y += clientStart.y + position.y;
758 return ((OptionBox)this).OptionBox_OnRightButtonDown(parent, x, y, mods);
763 typeExpected = directory, browseDialog = { };
764 editBox.OnRightButtonDown = (void *)EditBoxORB;
766 bool NotifyModified(PathBox pathBox)
768 ((OptionBox)pathBox.id).Retrieve();
773 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
775 String * string = (String*)((byte *)options + option);
776 String slashPath = ((PathBox)editor).slashPath;
777 if(*string) delete *string;
778 *string = CopyString(slashPath);//(slashPath && slashPath[0]) ? CopyString(slashPath) : null;
781 void LoadOption(ProjectOptions options)
783 ((PathBox)editor).path = options ? *(String*)((byte *)options + option) : "";
784 ((PathBox)editor).Deselect();
787 bool OptionCheck(ProjectOptions options)
789 String string = *(String*)((byte *)options + option);
790 return string && string[0];
793 void UnsetOption(ProjectOptions options)
795 delete *(String*)((byte *)options + option);
799 class MultiStringOptionBox : OptionBox<Array<String>>
804 caseSensitive = true;
806 virtual Array<String> GetStrings();
807 virtual void SetStrings(Array<String> value);
809 Array<String> tempStrings;
811 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
813 Array<String> newStrings = GetStrings();
814 Array<String> * strings = (Array<String>*)((byte *)options + option);
815 if(*strings) { strings->Free(); delete *strings; }
819 Iterator<String> it { newStrings };
821 FigureOutInherited();
825 Array<String> ts = tempStrings;
830 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
831 if(found && (!configReplaces || platform)) // ADDED || platform here...
841 if(!mergeValues || (configReplaces && isCfgOrPlt && !platform))
842 *strings = newStrings;
845 *strings = (newStrings && newStrings.count) ? newStrings : null;
846 if(newStrings && !newStrings.count) delete newStrings;
852 void LoadOption(ProjectOptions options)
856 Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
864 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
865 if(!found) tempStrings.Add(s);
871 SetStrings(options ? *(Array<String>*)((byte *)options + option) : null);
875 void FinalizeLoading()
879 SetStrings(tempStrings);
884 bool OptionSet(ProjectOptions options)
886 Array<String> strings = *(Array<String>*)((byte *)options + option);
887 if(mergeValues && !configReplaces)
889 return strings && strings.count;
892 return strings != null;
895 bool OptionCheck(ProjectOptions options)
897 Array<String> strings = *(Array<String>*)((byte *)options + option);
898 return strings && strings.count;
901 void UnsetOption(ProjectOptions options)
903 Array<String> * strings = (Array<String>*)((byte *)options + option);
904 if(*strings) { strings->Free(); delete *strings; }
908 class StringArrayOptionBox : MultiStringOptionBox
910 editor = StringListBox
912 bool NotifyModified(EditBox editBox)
914 ((OptionBox)editBox.id).Retrieve();
919 // NO VIRTUAL PROPERTIES YET...
920 Array<String> GetStrings() { return ((StringListBox)editor).strings; }
921 void SetStrings(Array<String> value) { ((StringListBox)editor).strings = value; }
924 class StringsArrayOptionBox : MultiStringOptionBox
934 bool NotifyModified(StringsBox stringsBox)
936 ((OptionBox)stringsBox.id).Retrieve();
941 Array<String> GetStrings() { return ((StringsBox)editor).strings; }
942 void SetStrings(Array<String> value) { ((StringsBox)editor).strings = value; }
945 class DirsArrayOptionBox : MultiStringOptionBox
947 editor = DirectoriesBox
949 bool NotifyModified(DirectoriesBox dirsBox)
951 ((OptionBox)dirsBox.id).Retrieve();
955 bool OnChangedDir(char * * directory)
957 char fixedDirectory[MAX_LOCATION] = "";
958 if(PathCat(fixedDirectory, *directory))
960 char cwdBackup[MAX_LOCATION];
963 GetWorkingDir(cwdBackup, sizeof(cwdBackup));
964 ChangeWorkingDir(project.topNode.path);
966 FileFixCase(fixedDirectory);
968 ChangeWorkingDir(cwdBackup);
970 *directory = CopyString(fixedDirectory);
976 bool OnPrepareBrowseDir(char * * directory)
978 char dir[MAX_LOCATION];
981 GetSystemPathBuffer(dir, project.topNode.path);
983 PathCat(dir, *directory);
986 strcpy(dir, *directory);
991 *directory = CopyString(dir);
993 // GCC 4.4 bug: ----- path becomes *directory
994 //strcpy(dir, path ? path : "");
998 bool OnBrowsedDir(char * * directory)
1002 char path[MAX_LOCATION];
1003 MakePathRelative(*directory, project.topNode.path, path);
1005 *directory = CopyString(path);
1011 Array<String> GetStrings() { return ((DirectoriesBox)editor).strings; }
1012 void SetStrings(Array<String> value) { ((DirectoriesBox)editor).strings = value; }
1015 class BoolOptionBox : OptionBox<SetBool>
1021 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1023 ((OptionBox)button.id).Retrieve();
1028 bool OptionCheck(ProjectOptions options)
1030 return *(SetBool*)((byte *)options + option) == true;
1033 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1035 bool checked = ((Button)editor).checked;
1036 *(SetBool*)((byte *)options + option) = checked ? true :
1037 ((currentNode.parent || isCfgOrPlt) ? false : unset);
1040 void LoadOption(ProjectOptions options)
1042 ((Button)editor).checked = options && (*(SetBool*)((byte *)options + option) == true);
1046 class CheckBoxForEnumOptionBox : OptionBox
1052 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1054 ((OptionBox)button.id).Retrieve();
1057 for(slave = master.firstSlave; slave; slave = slave.nextSlave)
1059 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
1060 slave != (Window)button.id &&
1061 ((OptionBox)slave).option == ((OptionBox)button.id).option)
1062 ((OptionBox)slave).Load();
1070 void LoadOption(ProjectOptions options)
1072 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1073 ((Button)editor).checked = value == enumValue;
1076 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1078 Button checkBox = (Button)editor;
1079 if(checkBox.checked)
1080 *(Z*)((byte *)options + option) = enumValue;
1084 class BuildBitDepthOptionBox : CheckBoxForEnumOptionBox<BuildBitDepth> { }
1086 class DropOptionBox : OptionBox
1090 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
1092 ((OptionBox)dropBox.id).Retrieve();
1097 void LoadOption(ProjectOptions options)
1099 DropBox dropBox = (DropBox)editor;
1100 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1101 dropBox.currentRow = value ? dropBox.FindRow((int64)value) : dropBox.firstRow;
1104 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1106 DropBox dropBox = (DropBox)editor;
1107 DataRow row = dropBox.currentRow;
1108 Z value = (Z)(row ? row.tag : 0);
1109 *(Z*)((byte *)options + option) = value;
1113 class TargetTypeDB : DropOptionBox<TargetTypes>
1119 row = ((DropBox)editor).AddRow();
1120 row.tag = TargetTypes::executable;
1121 row.SetData(null, $"Executable");
1123 row = ((DropBox)editor).AddRow();
1124 row.tag = TargetTypes::sharedLibrary;
1125 row.SetData(null, $"Shared Library");
1127 row = ((DropBox)editor).AddRow();
1128 row.tag = TargetTypes::staticLibrary;
1129 row.SetData(null, $"Static Library");
1132 bool OptionCheck(ProjectOptions options)
1134 TargetTypes value = *(TargetTypes*)((byte *)options + option);
1135 return value && value != executable;
1139 class OptimizationDB : DropOptionBox<OptimizationStrategy>
1144 row = ((DropBox)editor).AddRow();
1145 row.tag = OptimizationStrategy::none;
1146 row.SetData(null, $"None");
1148 row = ((DropBox)editor).AddRow();
1149 row.tag = OptimizationStrategy::speed;
1150 row.SetData(null, $"For Speed (-O2)");
1152 row = ((DropBox)editor).AddRow();
1153 row.tag = OptimizationStrategy::size;
1154 row.SetData(null, $"For Size (-Os)");
1157 bool OptionCheck(ProjectOptions options)
1159 OptimizationStrategy value = *(OptimizationStrategy*)((byte *)options + option);
1160 return value && value != none;
1164 class WarningsDB : DropOptionBox<WarningsOption>
1169 row = ((DropBox)editor).AddRow();
1170 row.tag = WarningsOption::normal;
1171 row.SetData(null, $"Normal");
1173 row = ((DropBox)editor).AddRow();
1174 row.tag = WarningsOption::none;
1175 row.SetData(null, $"None");
1177 row = ((DropBox)editor).AddRow();
1178 row.tag = WarningsOption::all;
1179 row.SetData(null, $"All");
1182 bool OptionCheck(ProjectOptions options)
1184 WarningsOption value = *(WarningsOption*)((byte *)options + option);
1185 return value && value != none;
1189 void DrawStipple(Surface surface, Size clientSize)
1193 int x2 = clientSize.w - 1;
1194 int y2 = clientSize.h - 1;
1195 if((x2 - x1) & 1) x2--;
1196 if((y2 - y1) & 1) y2--;
1198 surface.LineStipple(0x5555);
1199 surface.Rectangle(x1, y1, x2, y2);
1200 surface.LineStipple(0);
1203 class BuildTab : Tab
1206 background = formColor;
1209 ProjectNode backupNode;
1210 String activeConfigName;
1212 ProjectNode lastSelectedNode;
1214 property char * selectedConfigName
1220 SelectorButton button = (SelectorButton)configSelector.selectedButton;
1221 if(button && button.id)
1223 ProjectConfig config = (ProjectConfig)button.id;
1231 property char * selectedPlatformName
1237 SelectorButton button = (SelectorButton)platformSelector.selectedButton;
1238 if(button && button.id)
1240 Platform platform = (Platform)button.id;
1241 char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no?
1242 return platformName;
1249 Label labelConfigurations
1251 this, anchor = { left = 8, top = 14 }, labeledWindow = configSelector;
1253 void OnRedraw(Surface surface)
1255 Label::OnRedraw(surface);
1256 if(labeledWindow.active) DrawStipple(surface, clientSize);
1259 SelectorBar configSelector
1261 this, text = $"Configurations: ", anchor = { left = 98, top = 8, right = 54 }; size = { 0, 26 };
1263 direction = horizontal, scrollable = true;
1265 bool OnKeyDown(Key key, unichar ch)
1269 ((BuildTab)parent).createConfig.NotifyClicked(parent, ((BuildTab)parent).createConfig, 0, 0, 0);
1274 ((BuildTab)parent).deleteConfig.NotifyClicked(parent, ((BuildTab)parent).deleteConfig, 0, 0, 0);
1277 return SelectorBar::OnKeyDown(key, ch);
1280 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1282 ((BuildTab)master).labelConfigurations.Update(null);
1289 parent = this, bevelOver = true, inactive = true;
1291 anchor = { top = 10, right = 31 };
1292 hotKey = altC, bitmap = BitmapResource { fileName = ":actions/docNew.png", alphaBlend = true };
1294 bool NotifyClicked(Button b, int x, int y, Modifiers mods)
1296 char tmp[MAX_F_STRING];
1297 ProjectConfig config;
1298 EditableSelectorButton button;
1300 FindUniqueConfigName("NewConfig", false, tmp);
1304 makingModified = true;
1305 compilingModified = true;
1306 linkingModified = true;
1307 name = CopyString(tmp);
1310 // objectsDirectory = /*CopyString(*/defaultObjDirExpression/*)*/;
1313 if(!project.topNode.configurations) project.topNode.configurations = { };
1314 project.topNode.configurations.Add(config);
1316 targetType = project.config.options.targetType;
1318 config.options.targetFileName = project.moduleName;
1319 config.options.targetDir.dir = "";
1320 config.options.objectsDirectory = defaultObjDirExpression);
1321 config.options.debug = true;
1322 config.options.optimization = none;
1323 config.options.warnings = all;
1328 configSelector, renameable = true, master = this, text = config.name, id = (int64)config;
1329 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1332 configSelector.Select(button);
1333 modifiedDocument = true;
1337 /*Button duplicateConfig
1339 parent = this, bevelOver = true, inactive = true;
1341 anchor = { top = 10, right = 31 };
1342 hotKey = altU, bitmap = BitmapResource { fileName = ":actions/editCopy.png", alphaBlend = true };
1346 parent = this, bevelOver = true, inactive = true;
1348 anchor = { top = 10, right = 8 };
1349 hotKey = altD, bitmap = BitmapResource { fileName = ":actions/delete2.png", alphaBlend = true };
1351 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1355 String title = PrintString($"Delete ", config.name, $" Configuration");
1356 String msg = PrintString($"Are you sure you wish to delete the ", config.name, $" configuration?");
1357 if(MessageBox { type = okCancel, text = title, contents = msg }.Modal() == ok)
1359 Iterator<Window> it { configSelector.controls };
1360 ProjectConfig configToDelete = config;
1364 SelectorButton button = (SelectorButton)it.data;
1365 if((ProjectConfig)button.id == config)
1367 button.visible = false;
1372 button = (SelectorButton)it.data;
1373 config = (ProjectConfig)button.id;
1374 configSelector.Select(button);
1380 SelectorButton button = configSelector.FindButtonByID((int64)configToDelete);
1382 configSelector.RemoveButton(button);
1384 project.topNode.DeleteConfig(configToDelete);
1386 modifiedDocument = true;
1395 Label labelPlatforms
1397 this, anchor = { left = 8, top = 44 }, labeledWindow = platformSelector;
1399 void OnRedraw(Surface surface)
1401 Label::OnRedraw(surface);
1402 if(labeledWindow.active) DrawStipple(surface, clientSize);
1405 SelectorBar platformSelector
1407 this, text = $"Platforms: ", anchor = { left = 64, top = 38, right = 54 }; size = { 0, 26 };
1409 direction = horizontal, scrollable = true;
1411 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1413 ((BuildTab)master).labelPlatforms.Update(null);
1418 TabControl buildTabControl
1420 this, background = formColor, anchor = { left = 8, top = 64, right = 8, bottom = 8 };
1421 curTab = compilerTab;
1423 CompilerTab compilerTab { this, tabControl = buildTabControl };
1424 LinkerTab linkerTab { this, tabControl = buildTabControl };
1425 BuilderTab builderTab { this, tabControl = buildTabControl };
1428 this, font = { font.faceName, font.size, italic = true }, stayOnTop = true,
1429 text = $"(Right click or press Ctrl-Del to revert an option to inherited value)", anchor = { top = 72, right = 16 }
1432 void FindUniqueConfigName(char * baseName, bool startWithNumber, char * output)
1435 char tmp[MAX_F_STRING];
1437 sprintf(tmp, "%s%d", baseName, num);
1439 strcpy(tmp, baseName);
1442 ProjectConfig config = null;
1443 for(c : project.topNode.configurations)
1444 { // TOFIX: Error when omitting these brackets, c not found
1445 if(c.name && !strcmp(c.name, tmp))
1454 sprintf(tmp, "%s%d", baseName, num);
1459 strcpy(output, tmp);
1462 bool PlatformClicked(Button clickedButton, int x, int y, Modifiers mods)
1464 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1466 platform = (Platform)clickedButton.id;
1468 // Load Settings Into Dialog
1469 compilerTab.LoadSettings();
1470 linkerTab.LoadSettings();
1471 builderTab.LoadSettings();
1474 buildTabControl.Activate();
1476 if(compilerTab.rightPaneHeader.visible)
1477 compilerTab.rightPaneHeader.Update(null);
1478 ((ProjectSettings)master).UpdateDialogTitle();
1485 platformSelector.DestroyChildren();
1486 configSelector.DestroyChildren();
1488 delete activeConfigName;
1491 bool ConfigOnRename(EditableSelectorButton button, char * * oldName, char * * newName)
1496 for(c = 0; (ch = (*newName)[c]); c++)
1498 if(ch == '_' || isalpha(ch) || (isdigit(ch) && d))
1499 (*newName)[d++] = ch;
1505 for(c : project.topNode.configurations; c != config)
1507 if(!strcmpi(c.name, *newName))
1513 if(found || !(*newName)[0])
1515 char tmp[MAX_F_STRING];
1516 char * tmpName = config.name;
1518 FindUniqueConfigName("NewConfig", false, tmp);
1519 config.name = tmpName;
1521 *newName = CopyString(tmp);
1525 if(activeConfigName && !strcmp(activeConfigName, *oldName))
1527 delete activeConfigName;
1528 activeConfigName = CopyString(*newName);
1531 project.topNode.RenameConfig(config.name, *newName);
1533 modifiedDocument = true;
1537 bool ConfigClicked(Button clickedButton, int x, int y, Modifiers mods)
1539 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1541 config = (ProjectConfig)clickedButton.id;
1543 // Load Settings Into Dialog
1544 compilerTab.LoadSettings();
1545 linkerTab.LoadSettings();
1546 builderTab.LoadSettings();
1548 deleteConfig.disabled = (clickedButton._class == class(SelectorButton));
1551 buildTabControl.Activate();
1553 compilerTab.fileList.Update(null);
1554 if(compilerTab.rightPaneHeader.visible)
1555 compilerTab.rightPaneHeader.Update(null);
1556 ((ProjectSettings)master).UpdateDialogTitle();
1561 void SelectNode(ProjectNode node, bool ignoreAsLastSelection)
1563 if(node != currentNode)
1565 Window ac = compilerTab.rightPane.activeChild;
1566 bool prevNodeRes = currentNode ? currentNode.isInResources : false;
1569 if(!node) node = project.topNode;
1571 newNodeRes = node.isInResources;
1574 if(!ignoreAsLastSelection)
1575 lastSelectedNode = node;
1577 ((ProjectSettings)master).UpdateDialogTitle();
1578 if(node.type == project)
1580 compilerTab.rightPaneHeader.visible = false;
1584 compilerTab.rightPaneHeader.id = (int64)node;
1585 compilerTab.rightPaneHeader.Update(null);
1586 compilerTab.rightPaneHeader.visible = true;
1590 DataRow row = compilerTab.fileList.FindSubRow((int64)currentNode);
1593 compilerTab.fileList.currentRow = row;
1594 while((row = row.parent))
1595 row.collapsed = false;
1599 if(prevNodeRes != newNodeRes)
1601 compilerTab.labelObjDir.visible = !newNodeRes;
1602 compilerTab.objDir.visible = !newNodeRes;
1603 compilerTab.excludeFromBuild.visible = !newNodeRes;
1604 compilerTab.labelPreprocessorDefs.visible = !newNodeRes;
1605 compilerTab.preprocessorDefs.visible = !newNodeRes;
1606 compilerTab.labelDefaultNameSpace.visible = !newNodeRes;
1607 compilerTab.defaultNameSpace.visible = !newNodeRes;
1608 compilerTab.strictNameSpaces.visible = !newNodeRes;
1609 compilerTab.memoryGuard.visible = !newNodeRes;
1610 compilerTab.noLineNumbers.visible = !newNodeRes;
1611 compilerTab.debug.visible = !newNodeRes;
1612 compilerTab.labelWarnings.visible = !newNodeRes;
1613 compilerTab.warnings.visible = !newNodeRes;
1614 compilerTab.profiling.visible = !newNodeRes;
1615 compilerTab.labelOptimization.visible = !newNodeRes;
1616 compilerTab.optimization.visible = !newNodeRes;
1617 compilerTab.fastMath.visible = !newNodeRes;
1618 compilerTab.labelIncludeDirs.visible = !newNodeRes;
1619 compilerTab.includeDirs.visible = !newNodeRes;
1622 if(node == project.topNode)
1624 compilerTab.objDir.visible = true;
1625 compilerTab.labelObjDir.visible = true;
1627 compilerTab.excludeFromBuild.visible = false;
1631 compilerTab.objDir.visible = false;
1632 compilerTab.labelObjDir.visible = false;
1634 compilerTab.excludeFromBuild.visible = (node != project.resNode);
1637 // Load Settings Into Dialog
1638 compilerTab.LoadSettings();
1639 linkerTab.LoadSettings();
1640 builderTab.LoadSettings();
1646 if(ac == compilerTab.excludeFromBuild.editor)
1647 ac = compilerTab.objDir.editor;
1648 else if(compilerTab.excludeFromBuild.editor.visible)
1649 ac = compilerTab.excludeFromBuild.editor;
1656 void CreateConfigButtons()
1658 SelectorButton commonButton;
1660 // Create Config Buttons
1661 commonButton = SelectorButton
1663 configSelector, master = this, text = $"Common", id = (int64)null; font = { font.faceName, font.size, true };
1665 NotifyClicked = ConfigClicked;
1670 if(project.topNode.configurations)
1672 for(c : project.topNode.configurations)
1674 EditableSelectorButton button
1676 configSelector, master = this, renameable = true, text = c.name, id = (int64)c;
1677 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1686 SelectorButton button;
1688 activeConfigName = project.config ? CopyString(project.config.name) : null;
1690 compilerTab.AddNode(project.topNode, null);
1692 CreateConfigButtons();
1694 platformButton = button =
1696 platformSelector, master = this, text = $"Common", id = 0; font = { font.faceName, font.size, true };
1697 NotifyClicked = PlatformClicked; checked = true;
1702 for(p = (Platform)1; p < Platform::enumSize; p++)
1704 SelectorButton button
1706 platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p;
1707 NotifyClicked = PlatformClicked;
1711 SelectorButton platformButton;
1715 // Backup Current Settings
1716 backupNode = project.topNode.Backup();
1718 buildTabControl.Activate();
1721 Iterator<Window> it { configSelector.controls };
1724 SelectorButton configButton = (SelectorButton)it.data;
1725 ProjectConfig buttonConfig = (ProjectConfig)configButton.id;
1726 if(buttonConfig == project.config)
1728 configButton.Activate();
1729 configButton.checked = true;
1730 ConfigClicked(configButton, 0, 0, (Modifiers)null);
1737 platformButton.MakeActive();
1738 platformButton = null;
1747 lastSelectedNode = null;
1749 project.config = null;
1751 /* // THIS IS NOW AUTOMATED WITH A project CHECK IN ProjectNode
1752 project.configurations = project.topNode.configurations;
1753 project.platforms = project.topNode.platforms;
1754 project.options = project.topNode.options;
1757 if(project.topNode.configurations)
1759 for(c : project.topNode.configurations)
1761 if(!strcmpi(c.name, activeConfigName))
1770 void RevertChanges()
1772 String configName = config ? CopyString(config.name) : null;
1774 // Revert to saved project options
1775 project.topNode.Revert(backupNode);
1777 configSelector.DestroyChildren();
1778 CreateConfigButtons();
1780 // Reselect Configuration
1783 Iterator<Window> it { configSelector.controls };
1786 Button button = (Button)it.data;
1787 ProjectConfig c = (ProjectConfig)button.id;
1788 if(c && !strcmp(c.name, configName))
1792 button.checked = true;
1793 ConfigClicked(button, 0,0, 0);
1799 SelectNode(project.topNode, false);
1804 bool OnClose(bool parentClosing)
1806 if(modifiedDocument)
1808 DialogResult diagRes = MessageBox
1810 type = yesNoCancel, master = ide,
1811 text = $"Save changes to project settings?",
1812 contents = $"Would you like to save changes made to the build options?"
1816 if(diagRes == cancel)
1820 project.MarkChanges(backupNode);
1821 project.topNode.modified = true;
1822 ide.projectView.modifiedDocument = true;
1823 ide.UpdateToolBarActiveConfigs(false);
1824 ide.projectView.Update(null);
1826 modifiedDocument = false;
1832 class CompilerTab : Tab
1834 background = formColor;
1837 Window leftPane { this, size = { 180 }, anchor = { left = 0, top = 0, bottom = 0 }, background = formColor };
1839 Label labelFileList { leftPane, this, position = { 8, 8 }, labeledWindow = fileList };
1842 leftPane, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
1843 // THIS WOULD BE EVEN MORE FUN: multiSelect = true,
1844 fullRowSelect = false, collapseControl = true, treeBranches = true;
1845 alwaysHighLight = true;
1846 selectionColor = unfocusedSelectorColor;
1848 anchor = Anchor { left = 8, top = 24, right = 4, bottom = 8 };
1851 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1853 BuildTab buildTab = (BuildTab)master;
1854 ProjectNode node = (ProjectNode)row.tag;
1855 buildTab.SelectNode(node, false);
1859 void OnRedraw(Surface surface)
1861 ide.projectView.drawingInProjectSettingsDialog = true;
1862 ListBox::OnRedraw(surface);
1863 ide.projectView.drawingInProjectSettingsDialog = false;
1866 bool NotifyActivate(Window window, bool active, Window previous)
1870 //subclass(Skin) skinClass = (subclass(Skin))eSystem_FindClass(app, app.skin);
1871 fileList.selectionColor = Color { 10, 36, 106 }; //skinClass.selectionColor; // darkBlue;
1873 else if(fileList.currentRow)
1875 DataRow currentRow = fileList.currentRow;
1876 //int headerSize = ((fileList.style.header) ? fileList.rowHeight : 0);
1877 int height = fileList.clientSize.h + 1;// - fileList.headerSize;
1878 fileList.selectionColor = unfocusedSelectorColor;
1879 if(currentRow && currentRow.index * fileList.rowHeight > fileList.scroll.y + height - fileList.rowHeight)
1880 fileList.SetScrollPosition(fileList.scroll.x, currentRow.index * fileList.rowHeight - height + fileList.rowHeight);
1881 else if(!currentRow || currentRow.index * fileList.rowHeight < fileList.scroll.y)
1882 fileList.SetScrollPosition(fileList.scroll.x, currentRow ? currentRow.index * fileList.rowHeight : 0);
1892 this, anchor = { left = 196, top = 0, right = 0, bottom = 0 }, background = formColor, tabCycle = true;
1895 Window rightPaneHeader
1897 rightPane, this, size = { h = 21 }, anchor = { left = 0, top = 0, right = 0 }, background = Color { 70, 96, 166 };//0x0F3F66;
1898 foreground = white; visible = false;
1900 void OnRedraw(Surface surface)
1904 ide.projectView.drawingInProjectSettingsDialogHeader = true;
1905 ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(ProjectNode)._vTbl[__ecereVMethodID_class_OnDisplay])(class(ProjectNode),
1906 (void *)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
1907 ide.projectView.drawingInProjectSettingsDialogHeader = false;
1912 PaneSplitter splitter
1914 this, leftPane = leftPane, rightPane = rightPane, split = 188
1917 Label labelObjDir { rightPane, this, position = { 8, 8 }, labeledWindow = objDir };
1918 PathOptionBox objDir
1920 rightPane, this, size = { 250, 22 }, anchor = { left = 8, top = 24, right = 8 };
1921 text = $"Intermediate Objects Directory", hotKey = altJ, option = OPTION(objectsDirectory);
1924 BoolOptionBox excludeFromBuild
1926 rightPane, this, position = { 8, 28 },
1927 text = $"Exclude from Build", visible = false, option = OPTION(excludeFromBuild);
1930 Label labelPreprocessorDefs { rightPane, this, position = { 8, 50 }, labeledWindow = preprocessorDefs };
1931 StringArrayOptionBox preprocessorDefs
1933 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
1934 text = $"Preprocessor Definitions", hotKey = altD, option = OPTION(preprocessorDefinitions);
1937 Label labelDefaultNameSpace { rightPane, this, position = { 8, 92 }, labeledWindow = defaultNameSpace };
1938 StringOptionBox defaultNameSpace
1940 rightPane, this, size = { 160, 22 }, position = { 8, 108 };
1941 text = $"Default Name Space", option = OPTION(defaultNameSpace);
1943 BoolOptionBox strictNameSpaces
1945 rightPane, this, position = { 172, 112 },
1946 text = $"Strict Name Spaces", option = OPTION(strictNameSpaces);
1949 BoolOptionBox fastMath
1951 rightPane, this, position = { 316, 112 },
1952 text = $"Fast Math", option = OPTION(fastMath);
1955 BoolOptionBox memoryGuard
1957 rightPane, this, position = { 8, 154 };
1958 text = $"MemoryGuard", hotKey = altM, option = OPTION(memoryGuard);
1961 Label labelWarnings { rightPane, position = { 116, 138 }, labeledWindow = warnings };
1964 rightPane, this, position = { 116, 154 };
1965 text = $"Warnings", hotKey = altW, option = OPTION(warnings);
1968 Label labelOptimization { rightPane, position = { 220, 138 }, labeledWindow = optimization };
1969 OptimizationDB optimization
1971 rightPane, this, position = { 220, 154 }, size = { 120, 22 };
1972 text = $"Optimization", hotKey = altO, option = OPTION(optimization);
1977 rightPane, this, position = { 8, 188 };
1978 text = $"Debuggable", hotKey = altG, option = OPTION(debug);
1981 BoolOptionBox profiling
1983 rightPane, this, position = { 116, 188 };
1984 text = $"Profiling Data", hotKey = altP, option = OPTION(profile);
1987 BoolOptionBox noLineNumbers
1989 rightPane, this, position = { 220, 188 };
1990 text = $"No Line Numbers", hotKey = altN, option = OPTION(noLineNumbers);
1993 Label labelIncludeDirs { includeDirs.editor, labeledWindow = includeDirs, position = { 0, 6 }; };
1994 DirsArrayOptionBox includeDirs
1996 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 208, right = 8, bottom = 8 };
1997 text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs);
2002 fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false,
2003 userData = null /* Now set in the ProjectNode directly to know we're in ProjectSettings Dialog -- ide.projectView*/ });
2008 BuildTab buildTab = (BuildTab)master;
2009 buildTab.SelectNode(buildTab.lastSelectedNode, true);
2013 void AddNode(ProjectNode node, DataRow addTo)
2015 DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
2017 row.tag = (int64)node;
2019 row.SetData(null, node);
2021 if(node.files && node.files.first && node.parent &&
2022 !(!node.parent.parent &&
2023 (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") ||
2024 !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
2025 row.collapsed = true;
2026 else if(node.type == folder)
2027 node.icon = openFolder;
2031 for(child : node.files)
2032 AddNode(child, row);
2039 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2040 if(eClass_IsDerived(ob._class, class(OptionBox)))
2043 if(activeChild && activeChild.active)
2045 Window control = activeChild;
2046 control.Deactivate();
2053 objDir.editor.Activate();
2058 class LinkerTab : Tab
2060 background = formColor;
2063 Label labelTargetName { this, position = { 8, 8 }, labeledWindow = targetName };
2064 StringOptionBox targetName
2066 this, position = { 8, 24 }, size = { 200, 22 };
2067 text = $"Target Name", hotKey = altN, option = OPTION(targetFileName);
2070 Label labelTargetType { this, position = { 216, 8 }, labeledWindow = targetType };
2071 TargetTypeDB targetType
2073 this, position = { 216, 24 }, size = { 120, 22 };
2074 text = $"Target Type", hotKey = altT, option = OPTION(targetType);
2077 Label labelTargetDirectory { this, position = { 344, 8 }, labeledWindow = targetDirectory };
2078 PathOptionBox targetDirectory
2080 this, size = { 270, 22 }, anchor = { left = 344, top = 24, right = 8 };
2081 hotKey = altR, text = $"Target Directory", option = OPTION(targetDirectory);
2084 Label labelLibraries { this, position = { 8, 50 }, labeledWindow = libraries };
2085 StringArrayOptionBox libraries
2087 this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
2088 text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries);
2089 configReplaces = true;
2092 Label labelLinkerOptions { this, position = { 8, 92 }, labeledWindow = linkerOptions };
2093 StringArrayOptionBox linkerOptions
2095 this, size = { 290, 22 }, anchor = { left = 8, top = 108, right = 8 };
2096 text = $"Linker Options", hotKey = altO, option = OPTION(linkerOptions);
2097 configReplaces = true;
2100 BoolOptionBox console
2102 this, position = { 8, 138 };
2103 text = $"Console Application", hotKey = altC, option = OPTION(console);
2106 BoolOptionBox compress
2108 this, position = { 8, 162 };
2109 text = $"Compress", hotKey = altW, option = OPTION(compress);
2112 Label labelLibraryDirs { libraryDirs.editor, labeledWindow = libraryDirs, position = { 0, 6 }; };
2113 DirsArrayOptionBox libraryDirs
2115 this, size = { 290, 22 }, anchor = { left = 8, top = 182, right = 8, bottom = 8 };
2116 text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs);
2121 ((BuildTab)master).SelectNode(project.topNode, true);
2128 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2129 if(eClass_IsDerived(ob._class, class(OptionBox)))
2131 compress.disabled = (config && config.options && config.options.debug == true) || project.topNode.options.debug == true;
2133 if(activeChild && activeChild.active)
2135 Window control = activeChild;
2136 control.Deactivate();
2142 class BuilderTab : Tab
2144 background = formColor;
2147 Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
2148 StringsArrayOptionBox prebuildCommands
2150 this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
2151 text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
2154 Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
2155 StringsArrayOptionBox postbuildCommands
2157 this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
2158 text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
2163 bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
2165 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2166 if(eClass_IsDerived(ob._class, class(OptionBox)))
2169 if(activeChild && activeChild.active)
2171 Window control = activeChild;
2172 control.Deactivate();