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, char * switchToKeep, int lenSwitchToKeep)
14 String string = new char[len+1];
15 if(s[0] == '-' && switchToKeep && switchToKeep[0])
17 if(strstr(s+1, switchToKeep) == s+1)
19 memcpy(string, s+lenSwitchToKeep+1, len-lenSwitchToKeep-1);
20 string[len-lenSwitchToKeep-1] = '\0';
27 memcpy(string, s, len);
33 class StringListBox : EditBox
38 textHorzScroll = true;
40 property Array<String> strings
62 Array<String> array { };
64 char * contents = property::contents;
69 for(c = 0; (ch = contents[c]); c++)
71 if(ch == ' ' && !quoted)
75 if((s = MakeString(contents + start, c - start, switchToKeep, lenSwitchToKeep)))
90 if((s = MakeString(contents + start, c - start, switchToKeep, lenSwitchToKeep)))
98 define dialogTitle = $"Project Settings";
99 static Color unfocusedSelectorColor { 70, 96, 166 };
100 class ProjectSettings : Window
103 background = formColor;
104 borderStyle = sizable;
105 minClientSize = { 650, 520 };
110 property Project project
115 projectTab.project = value;
118 buildTab.SelectNode(project.topNode, false);
120 if(project && project.topNode && project.topNode.name && project.topNode.name[0])
123 get { return ::project; }
126 property ProjectNode projectNode
128 set { buildTab.SelectNode(value, false); }
129 get { return currentNode; }
132 void UpdateDialogTitle()
134 //char * s = PrintString("Project Settings - ", project.topNode.fileName);
136 char * projectName = new char[strlen(project.topNode.name) + 1];
137 char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
138 char * config = buildTab.selectedConfigName;
139 char * platform = buildTab.selectedPlatformName;
140 char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 +
141 strlen(nodeName) + 2 + strlen(config) + 1 + strlen(platform) + 1 + 1];
142 strcpy(label, dialogTitle);
143 strcat(label, " - ");
144 strcpy(projectName, project.topNode.name);
145 StripExtension(projectName);
146 strcat(label, projectName);
147 if(currentNode && currentNode.type != project)
149 strcat(label, " - ");
150 strcat(label, nodeName);
152 if(strlen(config) || strlen(platform))
156 strcat(label, config);
157 if(strlen(config) && strlen(platform))
160 strcat(label, platform);
173 TabControl prjTabControl
175 this, background = formColor, anchor = { left = 8, top = 4, right = 8, bottom = 38 };
177 ProjectTab projectTab { this, tabControl = prjTabControl };
178 BuildTab buildTab { this, tabControl = prjTabControl };
179 WorkspaceTab workspaceTab { this, tabControl = prjTabControl };
183 this, size = { 80, 22 };
184 anchor = { right = 8, bottom = 8 };
185 text = $"Cancel", hotKey = escape, id = DialogResult::cancel;
187 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
189 if(prjTabControl.curTab.modifiedDocument)
191 DialogResult diagRes = MessageBox
193 type = okCancel, master = ide,
194 text = $"Lose Changes?",
195 contents = $"Are you sure you wish to discard changes made to the build options?"
199 if(prjTabControl.curTab == buildTab)
201 buildTab.RevertChanges();
202 buildTab.modifiedDocument = false;
204 if(prjTabControl.curTab == workspaceTab)
206 workspaceTab.modifiedDocument = false;
208 if(prjTabControl.curTab == projectTab)
210 projectTab.modifiedDocument = false;
212 Destroy(DialogResult::cancel);
216 Destroy(DialogResult::cancel);
222 this, size = { 80, 22 };
223 anchor = { right = 96, bottom = 8 };
224 text = $"OK", isDefault = true;
226 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
228 if(prjTabControl.curTab == buildTab && buildTab.modifiedDocument)
230 buildTab.modifiedDocument = false;
232 project.topNode.modified = true;
233 project.MarkChanges(buildTab.backupNode);
234 ide.projectView.modifiedDocument = true;
235 ide.projectView.Update(null);
237 if(prjTabControl.curTab == workspaceTab && workspaceTab.modifiedDocument)
239 workspaceTab.SaveChanges();
240 workspaceTab.modifiedDocument = false;
242 if(prjTabControl.curTab == projectTab && projectTab.modifiedDocument)
244 projectTab.SaveChanges();
245 projectTab.modifiedDocument = false;
247 Destroy(DialogResult::ok);
255 prjTabControl.curTab = buildTab;
257 ((DirectoriesBox)buildTab.compilerTab.includeDirs.editor).baseBrowsePath = project.topNode.path;
258 ((DirectoriesBox)buildTab.linkerTab.libraryDirs.editor).baseBrowsePath = project.topNode.path;
264 #define OPTION(x) ((uint)(&((ProjectOptions)0).x))
266 // TOFIX: USING T INSTEAD OF Z HERE CAUSED US SOME CONFLICTS WITH T IN Array TEMPLATES
268 // the BlendFileConfigPlatformProjectOptions function and the GenericOptionTools class
269 // contain code that is closely matched to the following code
270 // output changing modification should be mirrored in both implementations
271 class OptionBox<class Z> : CommonControl
273 bool mergeValues, configReplaces;
282 property Window editor
288 editor.OnRightButtonDown = OptionBox_OnRightButtonDown;
289 chainKeyDown = (void *)editor.OnKeyDown;
290 editor.OnKeyDown = OptionBox_OnKeyDown;
294 property bool visible { set { editor.visible = value; } get { return editor.visible; } }
295 property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)this; } }
296 property Point position { set { editor.position = value; } }
297 property Size size { set { editor.size = value; } }
298 property Anchor anchor { set { editor.anchor = value; } }
299 property Key hotKey { set { editor.hotKey = value; } }
300 property char * text { set { editor.text = value; Window::text = value; } }
310 bool NotifySelect(MenuItem selection, Modifiers mods)
312 OptionBox ob = (OptionBox)id;
313 if(eClass_IsDerived(ob._class, class(CheckBoxForEnumOptionBox)))
316 for(slave = ob.master.firstSlave; slave; slave = slave.nextSlave)
318 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
319 ((OptionBox)slave).option == ob.option)
320 ((OptionBox)slave).Unset();
329 bool Window::OptionBox_OnRightButtonDown(int x, int y, Modifiers mods)
331 OptionBox ob = (OptionBox)id;
332 GuiApplication app = ((GuiApplication)__thisModule.application);
334 PopupMenu { null, this, menu = ob.clearMenu,
335 position = { absPosition.x + clientStart.x + x - app.desktop.position.x, absPosition.y + clientStart.y + y - app.desktop.position.y } }.Create();
339 bool Window::OptionBox_OnKeyDown(Key key, unichar ch)
341 OptionBox ob = (OptionBox)id;
342 if(key == Key { del, ctrl = true } || key == Key { keyPadDelete, ctrl = true })
347 return (((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
350 // code: 0 = not set anywhere, 1 = overridden here, 2 = inherited
351 void SetAttribs(int code)
356 for(c = Window::parent.firstChild; c; c = c.next)
358 if(eClass_IsDerived(c._class, class(Label)))
361 if(label.labeledWindow == this)
369 for(c = editor.firstChild; c; c = c.next)
371 if(eClass_IsDerived(c._class, class(Label)))
378 // control.foreground = foreground;
380 if(code == 0 || code == 1)
382 editor.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
383 editor.background = white;
387 Color foreground = 0x0F3F66;
388 int r = foreground.r, g = foreground.g, b = foreground.b;
392 editor.font = { editor.font.faceName, editor.font.size };
394 r = (int)(alpha * r + src.r * (1 - alpha));
395 g = (int)(alpha * g + src.g * (1 - alpha));
396 b = (int)(alpha * b + src.b * (1 - alpha));
398 r = Max(0,Min(255,r));
399 g = Max(0,Min(255,g));
400 b = Max(0,Min(255,b));
402 editor.background = Color { (byte) r, (byte) g, (byte) b };
407 label.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
408 //label.foreground = foreground;
412 virtual void FinalizeLoading();
414 virtual void LoadOption(ProjectOptions options);
415 virtual void RetrieveOption(ProjectOptions options, bool isCfgOrPlt);
416 virtual void UnsetOption(ProjectOptions options)
419 *(Z*)((byte *)options + option) = value;
422 virtual bool OptionSet(ProjectOptions options)
424 // TOFIX: If you get a crash here, it might be because JSON.ec must be after ProjectConfig.ec in the project files
425 // JSON.ec must also be before ProjectSettings.ec in the project files
426 if(*(Z*)((byte *)options + option))
430 // BUG: OptionCheck = OptionSet; // Overrides derived classes OptionCheck ?
432 virtual bool OptionCheck(ProjectOptions options)
434 return OptionSet(options);
437 void MarkBuildTabModified()
439 BuildTab buildTab = (BuildTab)master;
440 while(buildTab && buildTab._class != class(BuildTab))
441 buildTab = (BuildTab)buildTab.master;
442 if(buildTab) buildTab.modifiedDocument = true;
447 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
448 MarkBuildTabModified();
452 ProjectConfig c = null;
453 if(currentNode.configurations)
455 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
460 PlatformOptions p = null;
463 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
466 if(p.options && OptionSet(p.options))
467 UnsetOption(p.options);
468 if(p.options && p.options.isEmpty)
472 Iterator<PlatformOptions> it { c.platforms };
480 if(!c.platforms.count)
486 if(c.options && OptionSet(c.options))
487 UnsetOption(c.options);
488 if(c.options && c.options.isEmpty)
491 // DON'T DELETE PROJECT CONFIGS HERE!
492 if(!c.options && currentNode != project.topNode)
494 Iterator<ProjectConfig> it { currentNode.configurations };
502 if(!currentNode.configurations.count)
503 currentNode.configurations = null;
510 PlatformOptions p = null;
511 if(currentNode.platforms)
513 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
516 if(p.options && OptionSet(p.options))
517 UnsetOption(p.options);
518 if(p.options && p.options.isEmpty)
522 Iterator<PlatformOptions> it { currentNode.platforms };
530 if(!currentNode.platforms.count)
531 currentNode.platforms = null;
537 if(currentNode.options && OptionSet(currentNode.options))
538 UnsetOption(currentNode.options);
539 if(currentNode.options && currentNode.options.isEmpty)
541 // delete currentNode.options;
542 // Property will free:
543 currentNode.options = null;
549 void FigureOutInherited()
552 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
553 bool skipped = false;
554 for(node = currentNode; node; node = node.parent)
556 bool configXplatformSet = false;
557 if(config && node.configurations)
559 for(c : node.configurations; !strcmpi(c.name, config.name))
561 if(platform && c.platforms)
563 for(p : c.platforms; !strcmpi(p.name, platformName))
565 if(p.options && OptionSet(p.options))
568 LoadOption(p.options);
570 configXplatformSet = true;
576 if(skipped && c.options && OptionSet(c.options))
578 LoadOption(c.options);
579 if(configReplaces) return;
585 if((!configXplatformSet || !configReplaces) && platform && node.platforms)
587 for(p : node.platforms; !strcmpi(p.name, platformName))
589 if(skipped && p.options && OptionSet(p.options))
590 LoadOption(p.options);
595 if(skipped && node.options && OptionSet(node.options))
596 LoadOption(node.options);
597 else if(skipped && !node.parent)
605 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
606 MarkBuildTabModified();
609 ProjectConfig c = null;
610 if(!currentNode.configurations) currentNode.configurations = { };
611 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
613 currentNode.configurations.Add(c = ProjectConfig { name = CopyString(config.name) });
616 PlatformOptions p = null;
617 if(!c.platforms) c.platforms = { };
619 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
621 c.platforms.Add(p = PlatformOptions { CopyString(platformName) });
623 if(!p.options) p.options = { };
624 RetrieveOption(p.options, true);
625 if(!mergeValues) SetAttribs(1);
628 if(!c.options) c.options = { };
629 RetrieveOption(c.options, true);
630 if(!mergeValues) SetAttribs(1);
635 PlatformOptions p = null;
636 if(!currentNode.platforms) currentNode.platforms = { };
637 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
639 currentNode.platforms.Add(p = PlatformOptions { CopyString(platformName) });
641 if(!p.options) p.options = { };
642 RetrieveOption(p.options, true);
643 if(!mergeValues) SetAttribs(1);
647 if(!currentNode.options) currentNode.options = { };
648 RetrieveOption(currentNode.options, false);
649 if(!mergeValues) SetAttribs((currentNode.parent || OptionCheck(currentNode.options)) ? 1 : 0);
655 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
656 bool setAttribs = false;
657 for(node = currentNode; node; node = node.parent)
659 bool configXplatformSet = false;
660 ProjectConfig nodeConfig = null;
661 if(config && node.configurations)
663 for(c : node.configurations; !strcmpi(c.name, config.name))
665 if(platform && c.platforms)
667 for(p : c.platforms; !strcmpi(p.name, platformName))
669 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
671 LoadOption(p.options);
672 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode) ? 1 : 2); }
673 if(!mergeValues) { FinalizeLoading(); return; }
674 configXplatformSet = true;
684 if(platform && node.platforms && (!configXplatformSet || !configReplaces))
686 for(p : node.platforms; !strcmpi(p.name, platformName))
688 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
690 LoadOption(p.options);
691 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config) ? 1 : 2); }
692 if(!mergeValues) { FinalizeLoading(); return; }
698 if(nodeConfig && nodeConfig.options && ((mergeValues && !configReplaces) ? OptionCheck(nodeConfig.options) : OptionSet(nodeConfig.options)))
700 LoadOption(nodeConfig.options);
701 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !platform) ? 1 : 2); }
702 if(!mergeValues || configReplaces) { FinalizeLoading(); return; }
705 if(node.options && (mergeValues ? OptionCheck(node.options) : OptionSet(node.options)))
707 LoadOption(node.options);
708 if(!node.parent && !OptionCheck(node.options))
710 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
714 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config && !platform) ? 1 : 2); }
716 if(!mergeValues) { FinalizeLoading(); return; }
718 else if(!node.parent)
721 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
722 if(!mergeValues) { FinalizeLoading(); return; }
729 class StringOptionBox : OptionBox<String>
733 bool NotifyModified(EditBox editBox)
735 ((OptionBox)editBox.id).Retrieve();
739 textHorzScroll = true;
742 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
744 String * string = (String*)((byte *)options + option);
745 if(*string) delete *string;
746 *string = CopyString(((EditBox)editor).contents);
749 void LoadOption(ProjectOptions options)
751 ((EditBox)editor).contents = options ? *(String*)((byte *)options + option) : "";
752 ((EditBox)editor).Deselect();
755 bool OptionCheck(ProjectOptions options)
757 String string = *(String*)((byte *)options + option);
758 return string && string[0];
761 void UnsetOption(ProjectOptions options)
763 delete *(String*)((byte *)options + option);
767 class PathOptionBox : OptionBox<String>
769 bool Window::EditBoxORB(int x, int y, Modifiers mods)
771 Window parent = this.parent;
772 x += clientStart.x + position.x;
773 y += clientStart.y + position.y;
774 return ((OptionBox)this).OptionBox_OnRightButtonDown(parent, x, y, mods);
779 typeExpected = directory, browseDialog = { };
780 editBox.OnRightButtonDown = (void *)EditBoxORB;
782 bool NotifyModified(PathBox pathBox)
784 FixPathOnPathBoxNotifyModified(pathBox);
785 ((OptionBox)pathBox.id).Retrieve();
790 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
792 String * string = (String*)((byte *)options + option);
793 String slashPath = ((PathBox)editor).slashPath;
794 if(*string) delete *string;
795 *string = CopyString(slashPath);//(slashPath && slashPath[0]) ? CopyString(slashPath) : null;
798 void LoadOption(ProjectOptions options)
800 ((PathBox)editor).path = options ? *(String*)((byte *)options + option) : "";
801 ((PathBox)editor).Deselect();
804 bool OptionCheck(ProjectOptions options)
806 String string = *(String*)((byte *)options + option);
807 return string && string[0];
810 void UnsetOption(ProjectOptions options)
812 delete *(String*)((byte *)options + option);
816 class MultiStringOptionBox : OptionBox<Array<String>>
821 caseSensitive = true;
823 virtual Array<String> GetStrings();
824 virtual void SetStrings(Array<String> value);
826 Array<String> tempStrings;
828 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
830 Array<String> newStrings = GetStrings();
831 Array<String> * strings = (Array<String>*)((byte *)options + option);
832 if(*strings) { strings->Free(); delete *strings; }
836 Iterator<String> it { newStrings };
838 FigureOutInherited();
842 Array<String> ts = tempStrings;
847 for(i : tempStrings; i && s && !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
848 if(found && (!configReplaces || platform)) // ADDED || platform here...
858 if(!mergeValues || (configReplaces && isCfgOrPlt && !platform))
859 *strings = newStrings;
862 *strings = (newStrings && newStrings.count) ? newStrings : null;
863 if(newStrings && !newStrings.count) delete newStrings;
869 void LoadOption(ProjectOptions options)
873 Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
881 for(i : tempStrings; i && s && !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
882 if(!found) tempStrings.Add(s);
888 SetStrings(options ? *(Array<String>*)((byte *)options + option) : null);
892 void FinalizeLoading()
896 SetStrings(tempStrings);
901 bool OptionSet(ProjectOptions options)
903 Array<String> strings = *(Array<String>*)((byte *)options + option);
904 if(mergeValues && !configReplaces)
906 return strings && strings.count;
909 return strings != null;
912 bool OptionCheck(ProjectOptions options)
914 Array<String> strings = *(Array<String>*)((byte *)options + option);
915 return strings && strings.count;
918 void UnsetOption(ProjectOptions options)
920 Array<String> * strings = (Array<String>*)((byte *)options + option);
921 if(*strings) { strings->Free(); delete *strings; }
925 class StringArrayOptionBox : MultiStringOptionBox
927 editor = StringListBox
929 bool NotifyModified(EditBox editBox)
931 ((OptionBox)editBox.id).Retrieve();
936 // NO VIRTUAL PROPERTIES YET...
937 Array<String> GetStrings() { return ((StringListBox)editor).strings; }
938 void SetStrings(Array<String> value) { ((StringListBox)editor).strings = value; }
940 property char * switchToKeep { set { ((StringListBox)editor).switchToKeep = value; ((StringListBox)editor).lenSwitchToKeep = strlen(value); } };
943 class StringsArrayOptionBox : MultiStringOptionBox
953 bool NotifyModified(StringsBox stringsBox)
955 ((OptionBox)stringsBox.id).Retrieve();
960 Array<String> GetStrings() { return ((StringsBox)editor).strings; }
961 void SetStrings(Array<String> value) { ((StringsBox)editor).strings = value; }
964 bool eString_IsPathRelatedTo(char * path, char * to)
968 char rest[MAX_FILENAME];
969 char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION] = "";
970 char toPart[MAX_FILENAME], toRest[MAX_LOCATION] = "";
971 SplitDirectory(path, pathPart, pathRest);
972 SplitDirectory(to, toPart, toRest);
973 if(!fstrcmp(pathPart, toPart))
975 if(pathRest[0] && toRest[0])
977 SplitDirectory(pathRest, pathPart, pathRest);
978 SplitDirectory(toRest, toPart, toRest);
979 if(!fstrcmp(pathPart, toPart))
987 static void FixPathOnPathBoxNotifyModified(PathBox pathBox)
990 char path[MAX_LOCATION];
991 ValidPathBufCopy(path, pathBox.path);
993 if(len && !(path[0] == '.' && (len == 1 || (len == 2 && path[1] == DIR_SEP) || (len > 1 && path[1] == '.'))))
995 char cwdBackup[MAX_LOCATION];
998 GetWorkingDir(cwdBackup, sizeof(cwdBackup));
999 ChangeWorkingDir(project.topNode.path);
1003 ChangeWorkingDir(cwdBackup);
1004 if(eString_IsPathRelatedTo(path, project.topNode.path))
1005 MakePathRelative(path, project.topNode.path, path);
1010 if(len>1 && path[len-1] == DIR_SEP)
1012 pathBox.path = path;
1015 class DirsArrayOptionBox : MultiStringOptionBox
1018 property char * switchToKeep { set { switchToKeep = value; lenSwitchToKeep = strlen(value); } };
1020 char * switchToKeep;
1021 int lenSwitchToKeep;
1023 editor = DirectoriesBox
1026 bool NotifyModified(DirectoriesBox dirsBox)
1028 char * switchToKeep = ((DirsArrayOptionBox)dirsBox.id).switchToKeep;
1029 if(switchToKeep && switchToKeep[0])
1031 bool change = false;
1032 int lenSwitchToKeep = ((DirsArrayOptionBox)dirsBox.id).lenSwitchToKeep;
1033 Array<String> dirs { };
1034 Array<String> previousDirs = dirsBox.strings;
1035 for(d : previousDirs)
1038 char * buffer = new char[strlen(d)+64];
1039 char * tokens[1024];
1042 count = Tokenize(buffer, sizeof(tokens)/sizeof(tokens[0]), tokens, (BackSlashEscaping)false);
1043 for(c=0; c<count; c++)
1045 if(tokens[c][0] == '-')
1047 if(strstr(tokens[c]+1, switchToKeep) == tokens[c]+1)
1048 tokens[c] += lenSwitchToKeep+1;
1050 tokens[c][0] = '\0';
1053 dirs.Add(CopyString(tokens[c]));
1058 dirsBox.strings = dirs;
1061 previousDirs.Free();
1062 delete previousDirs;
1064 ((OptionBox)dirsBox.id).Retrieve();
1068 bool NotifyPathBoxModified(DirectoriesBox dirsBox, PathBox pathBox)
1070 FixPathOnPathBoxNotifyModified(pathBox);
1075 Array<String> GetStrings() { return ((DirectoriesBox)editor).strings; }
1076 void SetStrings(Array<String> value) { ((DirectoriesBox)editor).strings = value; }
1079 class BoolOptionBox : OptionBox<SetBool>
1085 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1087 ((OptionBox)button.id).Retrieve();
1092 bool OptionCheck(ProjectOptions options)
1094 return *(SetBool*)((byte *)options + option) == true;
1097 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1099 bool checked = ((Button)editor).checked;
1100 *(SetBool*)((byte *)options + option) = checked ? true :
1101 ((currentNode.parent || isCfgOrPlt) ? false : unset);
1104 void LoadOption(ProjectOptions options)
1106 ((Button)editor).checked = options && (*(SetBool*)((byte *)options + option) == true);
1110 class CheckBoxForEnumOptionBox : OptionBox
1116 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1118 ((OptionBox)button.id).Retrieve();
1121 for(slave = master.firstSlave; slave; slave = slave.nextSlave)
1123 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
1124 slave != (Window)button.id &&
1125 ((OptionBox)slave).option == ((OptionBox)button.id).option)
1126 ((OptionBox)slave).Load();
1134 void LoadOption(ProjectOptions options)
1136 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1137 ((Button)editor).checked = value == enumValue;
1140 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1142 Button checkBox = (Button)editor;
1143 if(checkBox.checked)
1144 *(Z*)((byte *)options + option) = enumValue;
1148 class BuildBitDepthOptionBox : CheckBoxForEnumOptionBox<BuildBitDepth> { }
1150 class DropOptionBox : OptionBox
1154 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
1156 ((OptionBox)dropBox.id).Retrieve();
1161 void LoadOption(ProjectOptions options)
1163 DropBox dropBox = (DropBox)editor;
1164 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1165 dropBox.currentRow = value ? dropBox.FindRow((int64)value) : dropBox.firstRow;
1168 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1170 DropBox dropBox = (DropBox)editor;
1171 DataRow row = dropBox.currentRow;
1172 Z value = (Z)(row ? row.tag : 0);
1173 *(Z*)((byte *)options + option) = value;
1177 class TargetTypeDB : DropOptionBox<TargetTypes>
1183 row = ((DropBox)editor).AddRow();
1184 row.tag = TargetTypes::executable;
1185 row.SetData(null, $"Executable");
1187 row = ((DropBox)editor).AddRow();
1188 row.tag = TargetTypes::sharedLibrary;
1189 row.SetData(null, $"Shared Library");
1191 row = ((DropBox)editor).AddRow();
1192 row.tag = TargetTypes::staticLibrary;
1193 row.SetData(null, $"Static Library");
1196 bool OptionCheck(ProjectOptions options)
1198 TargetTypes value = *(TargetTypes*)((byte *)options + option);
1199 return value && value != executable;
1203 class OptimizationDB : DropOptionBox<OptimizationStrategy>
1208 row = ((DropBox)editor).AddRow();
1209 row.tag = OptimizationStrategy::none;
1210 row.SetData(null, $"None");
1212 row = ((DropBox)editor).AddRow();
1213 row.tag = OptimizationStrategy::speed;
1214 row.SetData(null, $"For Speed (-O2)");
1216 row = ((DropBox)editor).AddRow();
1217 row.tag = OptimizationStrategy::size;
1218 row.SetData(null, $"For Size (-Os)");
1221 bool OptionCheck(ProjectOptions options)
1223 OptimizationStrategy value = *(OptimizationStrategy*)((byte *)options + option);
1224 return value && value != none;
1228 class WarningsDB : DropOptionBox<WarningsOption>
1233 row = ((DropBox)editor).AddRow();
1234 row.tag = WarningsOption::normal;
1235 row.SetData(null, $"Normal");
1237 row = ((DropBox)editor).AddRow();
1238 row.tag = WarningsOption::none;
1239 row.SetData(null, $"None");
1241 row = ((DropBox)editor).AddRow();
1242 row.tag = WarningsOption::all;
1243 row.SetData(null, $"All");
1246 bool OptionCheck(ProjectOptions options)
1248 WarningsOption value = *(WarningsOption*)((byte *)options + option);
1249 return value && value != none;
1253 void DrawStipple(Surface surface, Size clientSize)
1257 int x2 = clientSize.w - 1;
1258 int y2 = clientSize.h - 1;
1259 if((x2 - x1) & 1) x2--;
1260 if((y2 - y1) & 1) y2--;
1262 surface.LineStipple(0x5555);
1263 surface.Rectangle(x1, y1, x2, y2);
1264 surface.LineStipple(0);
1267 class BuildTab : Tab
1270 background = formColor;
1273 ProjectNode backupNode;
1274 String activeConfigName;
1276 ProjectNode lastSelectedNode;
1278 property char * selectedConfigName
1284 SelectorButton button = (SelectorButton)configSelector.selectedButton;
1285 if(button && button.id)
1287 ProjectConfig config = (ProjectConfig)button.id;
1295 property char * selectedPlatformName
1301 SelectorButton button = (SelectorButton)platformSelector.selectedButton;
1302 if(button && button.id)
1304 Platform platform = (Platform)button.id;
1305 char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no?
1306 return platformName;
1313 Label labelConfigurations
1315 this, anchor = { left = 8, top = 14 }, labeledWindow = configSelector;
1317 void OnRedraw(Surface surface)
1319 Label::OnRedraw(surface);
1320 if(labeledWindow.active) DrawStipple(surface, clientSize);
1323 SelectorBar configSelector
1325 this, text = $"Configurations: ", anchor = { left = 98, top = 8, right = 54 }; size = { 0, 26 };
1327 direction = horizontal, scrollable = true;
1329 bool OnKeyDown(Key key, unichar ch)
1333 ((BuildTab)parent).createConfig.NotifyClicked(parent, ((BuildTab)parent).createConfig, 0, 0, 0);
1338 ((BuildTab)parent).deleteConfig.NotifyClicked(parent, ((BuildTab)parent).deleteConfig, 0, 0, 0);
1341 return SelectorBar::OnKeyDown(key, ch);
1344 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1346 ((BuildTab)master).labelConfigurations.Update(null);
1353 parent = this, bevelOver = true, inactive = true;
1355 anchor = { top = 10, right = 31 };
1356 hotKey = altC, bitmap = BitmapResource { fileName = ":actions/docNew.png", alphaBlend = true };
1358 bool NotifyClicked(Button b, int x, int y, Modifiers mods)
1360 char tmp[MAX_F_STRING];
1361 ProjectConfig config;
1362 EditableSelectorButton button;
1364 FindUniqueConfigName("NewConfig", false, tmp);
1368 makingModified = true;
1369 compilingModified = true;
1370 linkingModified = true;
1371 name = CopyString(tmp);
1374 // objectsDirectory = /*CopyString(*/defaultObjDirExpression/*)*/;
1377 if(!project.topNode.configurations) project.topNode.configurations = { };
1378 project.topNode.configurations.Add(config);
1380 targetType = project.config.options.targetType;
1382 config.options.targetFileName = project.moduleName;
1383 config.options.targetDir.dir = "";
1384 config.options.objectsDirectory = defaultObjDirExpression);
1385 config.options.debug = true;
1386 config.options.optimization = none;
1387 config.options.warnings = all;
1392 configSelector, renameable = true, master = this, text = config.name, id = (int64)config;
1393 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1396 configSelector.Select(button);
1397 modifiedDocument = true;
1401 /*Button duplicateConfig
1403 parent = this, bevelOver = true, inactive = true;
1405 anchor = { top = 10, right = 31 };
1406 hotKey = altU, bitmap = BitmapResource { fileName = ":actions/editCopy.png", alphaBlend = true };
1410 parent = this, bevelOver = true, inactive = true;
1412 anchor = { top = 10, right = 8 };
1413 hotKey = altD, bitmap = BitmapResource { fileName = ":actions/delete2.png", alphaBlend = true };
1415 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1419 String title = PrintString($"Delete ", config.name, $" Configuration");
1420 String msg = PrintString($"Are you sure you wish to delete the ", config.name, $" configuration?");
1421 if(MessageBox { type = okCancel, text = title, contents = msg }.Modal() == ok)
1423 Iterator<Window> it { configSelector.controls };
1424 ProjectConfig configToDelete = config;
1428 SelectorButton button = (SelectorButton)it.data;
1429 if((ProjectConfig)button.id == config)
1431 button.visible = false;
1436 button = (SelectorButton)it.data;
1437 config = (ProjectConfig)button.id;
1438 configSelector.Select(button);
1444 SelectorButton button = configSelector.FindButtonByID((int64)configToDelete);
1446 configSelector.RemoveButton(button);
1448 project.topNode.DeleteConfig(configToDelete);
1450 modifiedDocument = true;
1459 Label labelPlatforms
1461 this, anchor = { left = 8, top = 44 }, labeledWindow = platformSelector;
1463 void OnRedraw(Surface surface)
1465 Label::OnRedraw(surface);
1466 if(labeledWindow.active) DrawStipple(surface, clientSize);
1469 SelectorBar platformSelector
1471 this, text = $"Platforms: ", anchor = { left = 64, top = 38, right = 54 }; size = { 0, 26 };
1473 direction = horizontal, scrollable = true;
1475 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1477 ((BuildTab)master).labelPlatforms.Update(null);
1482 TabControl buildTabControl
1484 this, background = formColor, anchor = { left = 8, top = 64, right = 8, bottom = 8 };
1485 curTab = compilerTab;
1487 CompilerTab compilerTab { this, tabControl = buildTabControl };
1488 LinkerTab linkerTab { this, tabControl = buildTabControl };
1489 BuilderTab builderTab { this, tabControl = buildTabControl };
1492 this, font = { font.faceName, font.size, italic = true }, stayOnTop = true,
1493 text = $"(Right click or press Ctrl-Del to revert an option to inherited value)", anchor = { top = 72, right = 16 }
1496 void FindUniqueConfigName(char * baseName, bool startWithNumber, char * output)
1499 char tmp[MAX_F_STRING];
1501 sprintf(tmp, "%s%d", baseName, num);
1503 strcpy(tmp, baseName);
1506 ProjectConfig config = null;
1507 for(c : project.topNode.configurations)
1508 { // TOFIX: Error when omitting these brackets, c not found
1509 if(c.name && !strcmp(c.name, tmp))
1518 sprintf(tmp, "%s%d", baseName, num);
1523 strcpy(output, tmp);
1526 bool PlatformClicked(Button clickedButton, int x, int y, Modifiers mods)
1528 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1530 platform = (Platform)clickedButton.id;
1532 // Load Settings Into Dialog
1533 compilerTab.LoadSettings();
1534 linkerTab.LoadSettings();
1535 builderTab.LoadSettings();
1538 buildTabControl.Activate();
1540 if(compilerTab.rightPaneHeader.visible)
1541 compilerTab.rightPaneHeader.Update(null);
1542 ((ProjectSettings)master).UpdateDialogTitle();
1549 platformSelector.DestroyChildren();
1550 configSelector.DestroyChildren();
1552 delete activeConfigName;
1555 bool ConfigOnRename(EditableSelectorButton button, char * * oldName, char * * newName)
1560 for(c = 0; (ch = (*newName)[c]); c++)
1562 if(ch == '_' || isalpha(ch) || (isdigit(ch) && d))
1563 (*newName)[d++] = ch;
1569 for(c : project.topNode.configurations; c != config)
1571 if(!strcmpi(c.name, *newName))
1577 if(found || !(*newName)[0])
1579 char tmp[MAX_F_STRING];
1580 char * tmpName = config.name;
1582 FindUniqueConfigName("NewConfig", false, tmp);
1583 config.name = tmpName;
1585 *newName = CopyString(tmp);
1589 if(activeConfigName && !strcmp(activeConfigName, *oldName))
1591 delete activeConfigName;
1592 activeConfigName = CopyString(*newName);
1595 project.topNode.RenameConfig(config.name, *newName);
1597 modifiedDocument = true;
1601 bool ConfigClicked(Button clickedButton, int x, int y, Modifiers mods)
1603 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1605 config = (ProjectConfig)clickedButton.id;
1607 // Load Settings Into Dialog
1608 compilerTab.LoadSettings();
1609 linkerTab.LoadSettings();
1610 builderTab.LoadSettings();
1612 deleteConfig.disabled = (clickedButton._class == class(SelectorButton));
1615 buildTabControl.Activate();
1617 compilerTab.fileList.Update(null);
1618 if(compilerTab.rightPaneHeader.visible)
1619 compilerTab.rightPaneHeader.Update(null);
1620 ((ProjectSettings)master).UpdateDialogTitle();
1625 void SelectNode(ProjectNode node, bool ignoreAsLastSelection)
1627 if(node != currentNode)
1629 Window ac = compilerTab.rightPane.activeChild;
1630 bool prevNodeRes = currentNode ? currentNode.isInResources : false;
1633 if(!node) node = project.topNode;
1635 newNodeRes = node.isInResources;
1638 if(!ignoreAsLastSelection)
1639 lastSelectedNode = node;
1641 ((ProjectSettings)master).UpdateDialogTitle();
1642 if(node.type == project)
1644 compilerTab.rightPaneHeader.visible = false;
1648 compilerTab.rightPaneHeader.id = (int64)node;
1649 compilerTab.rightPaneHeader.Update(null);
1650 compilerTab.rightPaneHeader.visible = true;
1654 DataRow row = compilerTab.fileList.FindSubRow((int64)currentNode);
1657 compilerTab.fileList.currentRow = row;
1658 while((row = row.parent))
1659 row.collapsed = false;
1663 if(prevNodeRes != newNodeRes)
1665 compilerTab.labelObjDir.visible = !newNodeRes;
1666 compilerTab.objDir.visible = !newNodeRes;
1667 compilerTab.excludeFromBuild.visible = !newNodeRes;
1668 compilerTab.labelPreprocessorDefs.visible = !newNodeRes;
1669 compilerTab.preprocessorDefs.visible = !newNodeRes;
1670 compilerTab.labelDefaultNameSpace.visible = !newNodeRes;
1671 compilerTab.defaultNameSpace.visible = !newNodeRes;
1672 compilerTab.strictNameSpaces.visible = !newNodeRes;
1673 compilerTab.memoryGuard.visible = !newNodeRes;
1674 compilerTab.noLineNumbers.visible = !newNodeRes;
1675 compilerTab.debug.visible = !newNodeRes;
1676 compilerTab.labelWarnings.visible = !newNodeRes;
1677 compilerTab.warnings.visible = !newNodeRes;
1678 compilerTab.profiling.visible = !newNodeRes;
1679 compilerTab.labelOptimization.visible = !newNodeRes;
1680 compilerTab.optimization.visible = !newNodeRes;
1681 compilerTab.fastMath.visible = !newNodeRes;
1682 compilerTab.labelIncludeDirs.visible = !newNodeRes;
1683 compilerTab.includeDirs.visible = !newNodeRes;
1686 if(node == project.topNode)
1688 compilerTab.objDir.visible = true;
1689 compilerTab.labelObjDir.visible = true;
1691 compilerTab.excludeFromBuild.visible = false;
1695 compilerTab.objDir.visible = false;
1696 compilerTab.labelObjDir.visible = false;
1698 compilerTab.excludeFromBuild.visible = (node != project.resNode);
1701 // Load Settings Into Dialog
1702 compilerTab.LoadSettings();
1703 linkerTab.LoadSettings();
1704 builderTab.LoadSettings();
1710 if(ac == compilerTab.excludeFromBuild.editor)
1711 ac = compilerTab.objDir.editor;
1712 else if(compilerTab.excludeFromBuild.editor.visible)
1713 ac = compilerTab.excludeFromBuild.editor;
1720 void CreateConfigButtons()
1722 SelectorButton commonButton;
1724 // Create Config Buttons
1725 commonButton = SelectorButton
1727 configSelector, master = this, text = $"Common", id = (int64)null; font = { font.faceName, font.size, true };
1729 NotifyClicked = ConfigClicked;
1734 if(project.topNode.configurations)
1736 for(c : project.topNode.configurations)
1738 EditableSelectorButton button
1740 configSelector, master = this, renameable = true, text = c.name, id = (int64)c;
1741 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1750 SelectorButton button;
1752 activeConfigName = project.config ? CopyString(project.config.name) : null;
1754 compilerTab.AddNode(project.topNode, null);
1756 CreateConfigButtons();
1758 platformButton = button =
1760 platformSelector, master = this, text = $"Common", id = 0; font = { font.faceName, font.size, true };
1761 NotifyClicked = PlatformClicked; checked = true;
1766 for(p = (Platform)1; p < Platform::enumSize; p++)
1768 SelectorButton button
1770 platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p;
1771 NotifyClicked = PlatformClicked;
1775 SelectorButton platformButton;
1779 // Backup Current Settings
1780 backupNode = project.topNode.Backup();
1782 buildTabControl.Activate();
1785 Iterator<Window> it { configSelector.controls };
1788 SelectorButton configButton = (SelectorButton)it.data;
1789 ProjectConfig buttonConfig = (ProjectConfig)configButton.id;
1790 if(buttonConfig == project.config)
1792 configButton.Activate();
1793 configButton.checked = true;
1794 ConfigClicked(configButton, 0, 0, (Modifiers)null);
1801 platformButton.MakeActive();
1802 platformButton = null;
1811 lastSelectedNode = null;
1813 project.config = null;
1815 /* // THIS IS NOW AUTOMATED WITH A project CHECK IN ProjectNode
1816 project.configurations = project.topNode.configurations;
1817 project.platforms = project.topNode.platforms;
1818 project.options = project.topNode.options;
1821 if(project.topNode.configurations)
1823 for(c : project.topNode.configurations)
1825 if(!strcmpi(c.name, activeConfigName))
1834 List<ProjectConfig> configs = project.topNode.configurations;
1835 if(configs && configs.count)
1836 project.config = configs[0];
1839 ide.UpdateToolBarActiveConfigs(false);
1842 void RevertChanges()
1844 String configName = config ? CopyString(config.name) : null;
1846 // Revert to saved project options
1847 project.topNode.Revert(backupNode);
1849 configSelector.DestroyChildren();
1850 CreateConfigButtons();
1852 // Reselect Configuration
1855 Iterator<Window> it { configSelector.controls };
1858 Button button = (Button)it.data;
1859 ProjectConfig c = (ProjectConfig)button.id;
1860 if(c && !strcmp(c.name, configName))
1864 button.checked = true;
1865 ConfigClicked(button, 0,0, 0);
1871 SelectNode(project.topNode, false);
1876 bool OnClose(bool parentClosing)
1878 if(modifiedDocument)
1880 DialogResult diagRes = MessageBox
1882 type = yesNoCancel, master = ide,
1883 text = $"Save changes to project settings?",
1884 contents = $"Would you like to save changes made to the build options?"
1888 if(diagRes == cancel)
1892 project.MarkChanges(backupNode);
1893 project.topNode.modified = true;
1894 ide.projectView.modifiedDocument = true;
1895 ide.UpdateToolBarActiveConfigs(false);
1896 ide.projectView.Update(null);
1898 modifiedDocument = false;
1904 class CompilerTab : Tab
1906 background = formColor;
1909 Window leftPane { this, size = { 180 }, anchor = { left = 0, top = 0, bottom = 0 }, background = formColor };
1911 Label labelFileList { leftPane, this, position = { 8, 8 }, labeledWindow = fileList };
1914 leftPane, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
1915 // THIS WOULD BE EVEN MORE FUN: multiSelect = true,
1916 fullRowSelect = false, collapseControl = true, treeBranches = true;
1917 alwaysHighLight = true;
1918 selectionColor = unfocusedSelectorColor;
1920 anchor = Anchor { left = 8, top = 24, right = 4, bottom = 8 };
1923 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1925 BuildTab buildTab = (BuildTab)master;
1926 ProjectNode node = (ProjectNode)row.tag;
1927 buildTab.SelectNode(node, false);
1931 void OnRedraw(Surface surface)
1933 ide.projectView.drawingInProjectSettingsDialog = true;
1934 ListBox::OnRedraw(surface);
1935 ide.projectView.drawingInProjectSettingsDialog = false;
1938 bool NotifyActivate(Window window, bool active, Window previous)
1942 //subclass(Skin) skinClass = (subclass(Skin))eSystem_FindClass(app, app.skin);
1943 fileList.selectionColor = Color { 10, 36, 106 }; //skinClass.selectionColor; // darkBlue;
1945 else if(fileList.currentRow)
1947 DataRow currentRow = fileList.currentRow;
1948 //int headerSize = ((fileList.style.header) ? fileList.rowHeight : 0);
1949 int height = fileList.clientSize.h + 1;// - fileList.headerSize;
1950 fileList.selectionColor = unfocusedSelectorColor;
1951 if(currentRow && currentRow.index * fileList.rowHeight > fileList.scroll.y + height - fileList.rowHeight)
1952 fileList.SetScrollPosition(fileList.scroll.x, currentRow.index * fileList.rowHeight - height + fileList.rowHeight);
1953 else if(!currentRow || currentRow.index * fileList.rowHeight < fileList.scroll.y)
1954 fileList.SetScrollPosition(fileList.scroll.x, currentRow ? currentRow.index * fileList.rowHeight : 0);
1964 this, anchor = { left = 196, top = 0, right = 0, bottom = 0 }, background = formColor, tabCycle = true;
1967 Window rightPaneHeader
1969 rightPane, this, size = { h = 21 }, anchor = { left = 0, top = 0, right = 0 }, background = Color { 70, 96, 166 };//0x0F3F66;
1970 foreground = white; visible = false;
1972 void OnRedraw(Surface surface)
1976 ide.projectView.drawingInProjectSettingsDialogHeader = true;
1977 ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(ProjectNode)._vTbl[__ecereVMethodID_class_OnDisplay])(class(ProjectNode),
1978 (void *)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
1979 ide.projectView.drawingInProjectSettingsDialogHeader = false;
1984 PaneSplitter splitter
1986 this, leftPane = leftPane, rightPane = rightPane, split = 188
1989 Label labelObjDir { rightPane, this, position = { 8, 8 }, labeledWindow = objDir };
1990 PathOptionBox objDir
1992 rightPane, this, size = { 250, 22 }, anchor = { left = 8, top = 24, right = 8 };
1993 text = $"Intermediate Objects Directory", hotKey = altJ, option = OPTION(objectsDirectory);
1996 BoolOptionBox excludeFromBuild
1998 rightPane, this, position = { 8, 28 },
1999 text = $"Exclude from Build", visible = false, option = OPTION(excludeFromBuild);
2002 Label labelPreprocessorDefs { rightPane, this, position = { 8, 50 }, labeledWindow = preprocessorDefs };
2003 StringArrayOptionBox preprocessorDefs
2005 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
2006 text = $"Preprocessor Definitions", hotKey = altD, option = OPTION(preprocessorDefinitions);
2009 Label labelDefaultNameSpace { rightPane, this, position = { 8, 92 }, labeledWindow = defaultNameSpace };
2010 StringOptionBox defaultNameSpace
2012 rightPane, this, size = { 160, 22 }, position = { 8, 108 };
2013 text = $"Default Name Space", option = OPTION(defaultNameSpace);
2015 BoolOptionBox strictNameSpaces
2017 rightPane, this, position = { 172, 112 },
2018 text = $"Strict Name Spaces", option = OPTION(strictNameSpaces);
2021 BoolOptionBox fastMath
2023 rightPane, this, position = { 316, 112 },
2024 text = $"Fast Math", option = OPTION(fastMath);
2027 BoolOptionBox memoryGuard
2029 rightPane, this, position = { 8, 154 };
2030 text = $"MemoryGuard", hotKey = altM, option = OPTION(memoryGuard);
2033 Label labelWarnings { rightPane, position = { 116, 138 }, labeledWindow = warnings };
2036 rightPane, this, position = { 116, 154 };
2037 text = $"Warnings", hotKey = altW, option = OPTION(warnings);
2040 Label labelOptimization { rightPane, position = { 220, 138 }, labeledWindow = optimization };
2041 OptimizationDB optimization
2043 rightPane, this, position = { 220, 154 }, size = { 120, 22 };
2044 text = $"Optimization", hotKey = altO, option = OPTION(optimization);
2049 rightPane, this, position = { 8, 188 };
2050 text = $"Debuggable", hotKey = altG, option = OPTION(debug);
2053 BoolOptionBox profiling
2055 rightPane, this, position = { 116, 188 };
2056 text = $"Profiling Data", hotKey = altP, option = OPTION(profile);
2059 BoolOptionBox noLineNumbers
2061 rightPane, this, position = { 220, 188 };
2062 text = $"No Line Numbers", hotKey = altN, option = OPTION(noLineNumbers);
2065 Label labelCompilerOptions { rightPane, this, position = { 8, 208 }, labeledWindow = compilerOptions };
2066 StringArrayOptionBox compilerOptions
2068 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 224, right = 8 };
2069 text = $"Compiler Options", hotKey = altO, option = OPTION(compilerOptions);
2070 configReplaces = true;
2073 Label labelIncludeDirs { includeDirs.editor, labeledWindow = includeDirs, position = { 0, 6 }; };
2074 DirsArrayOptionBox includeDirs
2076 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 250, right = 8, bottom = 8 };
2077 text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs), switchToKeep = "I";
2082 fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false,
2083 userData = null /* Now set in the ProjectNode directly to know we're in ProjectSettings Dialog -- ide.projectView*/ });
2088 BuildTab buildTab = (BuildTab)master;
2089 buildTab.SelectNode(buildTab.lastSelectedNode, true);
2093 void AddNode(ProjectNode node, DataRow addTo)
2095 DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
2097 row.tag = (int64)node;
2099 row.SetData(null, node);
2101 if(node.files && node.files.first && node.parent &&
2102 !(!node.parent.parent &&
2103 (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") ||
2104 !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
2105 row.collapsed = true;
2106 else if(node.type == folder)
2107 node.icon = openFolder;
2111 for(child : node.files)
2112 AddNode(child, row);
2119 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2120 if(eClass_IsDerived(ob._class, class(OptionBox)))
2123 if(activeChild && activeChild.active)
2125 Window control = activeChild;
2126 control.Deactivate();
2133 objDir.editor.Activate();
2138 class LinkerTab : Tab
2140 background = formColor;
2143 Label labelTargetName { this, position = { 8, 8 }, labeledWindow = targetName };
2144 StringOptionBox targetName
2146 this, position = { 8, 24 }, size = { 200, 22 };
2147 text = $"Target Name", hotKey = altN, option = OPTION(targetFileName);
2150 Label labelTargetType { this, position = { 216, 8 }, labeledWindow = targetType };
2151 TargetTypeDB targetType
2153 this, position = { 216, 24 }, size = { 120, 22 };
2154 text = $"Target Type", hotKey = altT, option = OPTION(targetType);
2157 Label labelTargetDirectory { this, position = { 344, 8 }, labeledWindow = targetDirectory };
2158 PathOptionBox targetDirectory
2160 this, size = { 270, 22 }, anchor = { left = 344, top = 24, right = 8 };
2161 hotKey = altR, text = $"Target Directory", option = OPTION(targetDirectory);
2164 Label labelLibraries { this, position = { 8, 50 }, labeledWindow = libraries };
2165 StringArrayOptionBox libraries
2167 this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
2168 text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries), switchToKeep = "l";
2169 configReplaces = true;
2172 Label labelLinkerOptions { this, position = { 8, 92 }, labeledWindow = linkerOptions };
2173 StringArrayOptionBox linkerOptions
2175 this, size = { 290, 22 }, anchor = { left = 8, top = 108, right = 8 };
2176 text = $"Linker Options", hotKey = altO, option = OPTION(linkerOptions);
2177 configReplaces = true;
2180 BoolOptionBox console
2182 this, position = { 8, 138 };
2183 text = $"Console Application", hotKey = altC, option = OPTION(console);
2186 BoolOptionBox compress
2188 this, position = { 8, 162 };
2189 text = $"Compress", hotKey = altW, option = OPTION(compress);
2192 Label labelLibraryDirs { libraryDirs.editor, labeledWindow = libraryDirs, position = { 0, 6 }; };
2193 DirsArrayOptionBox libraryDirs
2195 this, size = { 290, 22 }, anchor = { left = 8, top = 182, right = 8, bottom = 8 };
2196 text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs), switchToKeep = "L";
2201 ((BuildTab)master).SelectNode(project.topNode, true);
2208 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2209 if(eClass_IsDerived(ob._class, class(OptionBox)))
2211 compress.disabled = (config && config.options && config.options.debug == true) || project.topNode.options.debug == true;
2213 if(activeChild && activeChild.active)
2215 Window control = activeChild;
2216 control.Deactivate();
2222 class BuilderTab : Tab
2224 background = formColor;
2227 Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
2228 StringsArrayOptionBox prebuildCommands
2230 this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
2231 text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
2234 Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
2235 StringsArrayOptionBox postbuildCommands
2237 this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
2238 text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
2243 bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
2245 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2246 if(eClass_IsDerived(ob._class, class(OptionBox)))
2249 if(activeChild && activeChild.active)
2251 Window control = activeChild;
2252 control.Deactivate();