2 import "WorkspaceSettings"
3 import "ProjectTabSettings"
5 // import "SelectorBar"
7 static ProjectConfig config;
8 static Platform platform;
9 static ProjectNode currentNode;
10 static Project project;
12 static String MakeString(char * s, int len)
14 String string = new char[len+1];
15 memcpy(string, s, len);
20 class StringListBox : EditBox
22 textHorzScroll = true;
24 property Array<String> strings
43 Array<String> array { };
45 char * contents = property::contents;
49 for(c = 0; (ch = contents[c]); c++)
51 if(ch == ' ' && !quoted)
54 array.Add(MakeString(contents + start, c - start));
66 array.Add(MakeString(contents + start, c - start));
72 define dialogTitle = $"Project Settings";
73 static Color unfocusedSelectorColor { 70, 96, 166 };
74 class ProjectSettings : Window
77 background = formColor;
78 borderStyle = sizable;
79 minClientSize = { 650, 520 };
84 property Project project
89 projectTab.project = value;
92 buildTab.SelectNode(project.topNode, false);
94 if(project && project.topNode && project.topNode.name && project.topNode.name[0])
97 get { return ::project; }
100 property ProjectNode projectNode
102 set { buildTab.SelectNode(value, false); }
103 get { return currentNode; }
106 void UpdateDialogTitle()
108 //char * s = PrintString("Project Settings - ", project.topNode.fileName);
110 char * projectName = new char[strlen(project.topNode.name) + 1];
111 char * nodeName = currentNode && currentNode != project.topNode ? currentNode.name : "";
112 char * config = buildTab.selectedConfigName;
113 char * platform = buildTab.selectedPlatformName;
114 char * label = new char[strlen(dialogTitle) + 3 + strlen(project.topNode.name) + 3 +
115 strlen(nodeName) + 2 + strlen(config) + 1 + strlen(platform) + 1 + 1];
116 strcpy(label, dialogTitle);
117 strcat(label, " - ");
118 strcpy(projectName, project.topNode.name);
119 StripExtension(projectName);
120 strcat(label, projectName);
121 if(currentNode && currentNode.type != project)
123 strcat(label, " - ");
124 strcat(label, nodeName);
126 if(strlen(config) || strlen(platform))
130 strcat(label, config);
131 if(strlen(config) && strlen(platform))
134 strcat(label, platform);
147 TabControl prjTabControl
149 this, background = formColor, anchor = { left = 8, top = 4, right = 8, bottom = 38 };
151 ProjectTab projectTab { this, tabControl = prjTabControl };
152 BuildTab buildTab { this, tabControl = prjTabControl };
153 WorkspaceTab workspaceTab { this, tabControl = prjTabControl };
157 this, size = { 80, 22 };
158 anchor = { right = 8, bottom = 8 };
159 text = $"Cancel", hotKey = escape, id = DialogResult::cancel;
161 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
163 if(prjTabControl.curTab.modifiedDocument)
165 DialogResult diagRes = MessageBox
167 type = okCancel, master = ide,
168 text = $"Lose Changes?",
169 contents = $"Are you sure you wish to discard changes made to the build options?"
173 if(prjTabControl.curTab == buildTab)
175 buildTab.RevertChanges();
176 buildTab.modifiedDocument = false;
178 if(prjTabControl.curTab == workspaceTab)
180 workspaceTab.modifiedDocument = false;
182 if(prjTabControl.curTab == projectTab)
184 projectTab.modifiedDocument = false;
186 Destroy(DialogResult::cancel);
190 Destroy(DialogResult::cancel);
196 this, size = { 80, 22 };
197 anchor = { right = 96, bottom = 8 };
198 text = $"OK", isDefault = true;
200 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
202 if(prjTabControl.curTab == buildTab && buildTab.modifiedDocument)
204 buildTab.modifiedDocument = false;
206 project.topNode.modified = true;
207 project.MarkChanges(buildTab.backupNode);
208 ide.projectView.modifiedDocument = true;
209 ide.projectView.Update(null);
211 if(prjTabControl.curTab == workspaceTab && workspaceTab.modifiedDocument)
213 workspaceTab.SaveChanges();
214 workspaceTab.modifiedDocument = false;
216 if(prjTabControl.curTab == projectTab && projectTab.modifiedDocument)
218 projectTab.SaveChanges();
219 projectTab.modifiedDocument = false;
221 Destroy(DialogResult::ok);
229 prjTabControl.curTab = buildTab;
231 ((DirectoriesBox)buildTab.compilerTab.includeDirs.editor).baseBrowsePath = project.topNode.path;
232 ((DirectoriesBox)buildTab.linkerTab.libraryDirs.editor).baseBrowsePath = project.topNode.path;
238 #define OPTION(x) ((uint)(&((ProjectOptions)0).x))
240 // TOFIX: USING T INSTEAD OF Z HERE CAUSED US SOME CONFLICTS WITH T IN Array TEMPLATES
242 // the BlendFileConfigPlatformProjectOptions function and the GenericOptionTools class
243 // contain code that is closely matched to the following code
244 // output changing modification should be mirrored in both implementations
245 class OptionBox<class Z> : CommonControl
247 bool mergeValues, configReplaces;
256 property Window editor
262 editor.OnRightButtonDown = OptionBox_OnRightButtonDown;
263 chainKeyDown = (void *)editor.OnKeyDown;
264 editor.OnKeyDown = OptionBox_OnKeyDown;
268 property bool visible { set { editor.visible = value; } get { return editor.visible; } }
269 property Window parent { set { editor.parent = value; Window::parent = value; master = value; editor.id = (int64)this; } }
270 property Point position { set { editor.position = value; } }
271 property Size size { set { editor.size = value; } }
272 property Anchor anchor { set { editor.anchor = value; } }
273 property Key hotKey { set { editor.hotKey = value; } }
274 property char * text { set { editor.text = value; Window::text = value; } }
284 bool NotifySelect(MenuItem selection, Modifiers mods)
286 OptionBox ob = (OptionBox)id;
287 if(eClass_IsDerived(ob._class, class(CheckBoxForEnumOptionBox)))
290 for(slave = ob.master.firstSlave; slave; slave = slave.nextSlave)
292 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
293 ((OptionBox)slave).option == ob.option)
294 ((OptionBox)slave).Unset();
303 bool Window::OptionBox_OnRightButtonDown(int x, int y, Modifiers mods)
305 OptionBox ob = (OptionBox)id;
306 GuiApplication app = ((GuiApplication)__thisModule.application);
308 PopupMenu { null, this, menu = ob.clearMenu,
309 position = { absPosition.x + clientStart.x + x - app.desktop.position.x, absPosition.y + clientStart.y + y - app.desktop.position.y } }.Create();
313 bool Window::OptionBox_OnKeyDown(Key key, unichar ch)
315 OptionBox ob = (OptionBox)id;
316 if(key == Key { del, ctrl = true } || key == Key { keyPadDelete, ctrl = true })
321 return (((bool(*)(Window, Key, unichar)) ob.chainKeyDown)(this, key, ch);
324 // code: 0 = not set anywhere, 1 = overridden here, 2 = inherited
325 void SetAttribs(int code)
330 for(c = Window::parent.firstChild; c; c = c.next)
332 if(eClass_IsDerived(c._class, class(Label)))
335 if(label.labeledWindow == this)
343 for(c = editor.firstChild; c; c = c.next)
345 if(eClass_IsDerived(c._class, class(Label)))
352 // control.foreground = foreground;
354 if(code == 0 || code == 1)
356 editor.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
357 editor.background = white;
361 Color foreground = 0x0F3F66;
362 int r = foreground.r, g = foreground.g, b = foreground.b;
366 editor.font = { editor.font.faceName, editor.font.size };
368 r = (int)(alpha * r + src.r * (1 - alpha));
369 g = (int)(alpha * g + src.g * (1 - alpha));
370 b = (int)(alpha * b + src.b * (1 - alpha));
372 r = Max(0,Min(255,r));
373 g = Max(0,Min(255,g));
374 b = Max(0,Min(255,b));
376 editor.background = Color { (byte) r, (byte) g, (byte) b };
381 label.font = { editor.font.faceName, editor.font.size, bold = (code == 1) };
382 //label.foreground = foreground;
386 virtual void FinalizeLoading();
388 virtual void LoadOption(ProjectOptions options);
389 virtual void RetrieveOption(ProjectOptions options, bool isCfgOrPlt);
390 virtual void UnsetOption(ProjectOptions options)
393 *(Z*)((byte *)options + option) = value;
396 virtual bool OptionSet(ProjectOptions options)
398 // TOFIX: If you get a crash here, it might be because JSON.ec must be after ProjectConfig.ec in the project files
399 // JSON.ec must also be before ProjectSettings.ec in the project files
400 if(*(Z*)((byte *)options + option))
404 // BUG: OptionCheck = OptionSet; // Overrides derived classes OptionCheck ?
406 virtual bool OptionCheck(ProjectOptions options)
408 return OptionSet(options);
411 void MarkBuildTabModified()
413 BuildTab buildTab = (BuildTab)master;
414 while(buildTab && buildTab._class != class(BuildTab))
415 buildTab = (BuildTab)buildTab.master;
416 if(buildTab) buildTab.modifiedDocument = true;
421 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
422 MarkBuildTabModified();
426 ProjectConfig c = null;
427 if(currentNode.configurations)
429 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
434 PlatformOptions p = null;
437 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
440 if(p.options && OptionSet(p.options))
441 UnsetOption(p.options);
442 if(p.options && p.options.isEmpty)
446 Iterator<PlatformOptions> it { c.platforms };
454 if(!c.platforms.count)
460 if(c.options && OptionSet(c.options))
461 UnsetOption(c.options);
462 if(c.options && c.options.isEmpty)
465 // DON'T DELETE PROJECT CONFIGS HERE!
466 if(!c.options && currentNode != project.topNode)
468 Iterator<ProjectConfig> it { currentNode.configurations };
476 if(!currentNode.configurations.count)
477 currentNode.configurations = null;
484 PlatformOptions p = null;
485 if(currentNode.platforms)
487 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
490 if(p.options && OptionSet(p.options))
491 UnsetOption(p.options);
492 if(p.options && p.options.isEmpty)
496 Iterator<PlatformOptions> it { currentNode.platforms };
504 if(!currentNode.platforms.count)
505 currentNode.platforms = null;
511 if(currentNode.options && OptionSet(currentNode.options))
512 UnsetOption(currentNode.options);
513 if(currentNode.options && currentNode.options.isEmpty)
515 // delete currentNode.options;
516 // Property will free:
517 currentNode.options = null;
523 void FigureOutInherited()
526 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
527 bool skipped = false;
528 for(node = currentNode; node; node = node.parent)
530 bool configXplatformSet = false;
531 if(config && node.configurations)
533 for(c : node.configurations; !strcmpi(c.name, config.name))
535 if(platform && c.platforms)
537 for(p : c.platforms; !strcmpi(p.name, platformName))
539 if(p.options && OptionSet(p.options))
542 LoadOption(p.options);
544 configXplatformSet = true;
550 if(skipped && c.options && OptionSet(c.options))
552 LoadOption(c.options);
553 if(configReplaces) return;
559 if((!configXplatformSet || !configReplaces) && platform && node.platforms)
561 for(p : node.platforms; !strcmpi(p.name, platformName))
563 if(skipped && p.options && OptionSet(p.options))
564 LoadOption(p.options);
569 if(skipped && node.options && OptionSet(node.options))
570 LoadOption(node.options);
571 else if(skipped && !node.parent)
579 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
580 MarkBuildTabModified();
583 ProjectConfig c = null;
584 if(!currentNode.configurations) currentNode.configurations = { };
585 for(i : currentNode.configurations; !strcmpi(i.name, config.name)) { c = i; break; }
587 currentNode.configurations.Add(c = ProjectConfig { name = CopyString(config.name) });
590 PlatformOptions p = null;
591 if(!c.platforms) c.platforms = { };
593 for(i : c.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
595 c.platforms.Add(p = PlatformOptions { CopyString(platformName) });
597 if(!p.options) p.options = { };
598 RetrieveOption(p.options, true);
599 if(!mergeValues) SetAttribs(1);
602 if(!c.options) c.options = { };
603 RetrieveOption(c.options, true);
604 if(!mergeValues) SetAttribs(1);
609 PlatformOptions p = null;
610 if(!currentNode.platforms) currentNode.platforms = { };
611 for(i : currentNode.platforms; !strcmpi(i.name, platformName)) { p = i; break; }
613 currentNode.platforms.Add(p = PlatformOptions { CopyString(platformName) });
615 if(!p.options) p.options = { };
616 RetrieveOption(p.options, true);
617 if(!mergeValues) SetAttribs(1);
621 if(!currentNode.options) currentNode.options = { };
622 RetrieveOption(currentNode.options, false);
623 if(!mergeValues) SetAttribs((currentNode.parent || OptionCheck(currentNode.options)) ? 1 : 0);
629 char * platformName = platform ? platform.OnGetString(0,0,0) : null;
630 bool setAttribs = false;
631 for(node = currentNode; node; node = node.parent)
633 bool configXplatformSet = false;
634 ProjectConfig nodeConfig = null;
635 if(config && node.configurations)
637 for(c : node.configurations; !strcmpi(c.name, config.name))
639 if(platform && c.platforms)
641 for(p : c.platforms; !strcmpi(p.name, platformName))
643 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
645 LoadOption(p.options);
646 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode) ? 1 : 2); }
647 if(!mergeValues) { FinalizeLoading(); return; }
648 configXplatformSet = true;
658 if(platform && node.platforms && (!configXplatformSet || !configReplaces))
660 for(p : node.platforms; !strcmpi(p.name, platformName))
662 if(p.options && (mergeValues ? OptionCheck(p.options) : OptionSet(p.options)))
664 LoadOption(p.options);
665 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config) ? 1 : 2); }
666 if(!mergeValues) { FinalizeLoading(); return; }
672 if(nodeConfig && nodeConfig.options && ((mergeValues && !configReplaces) ? OptionCheck(nodeConfig.options) : OptionSet(nodeConfig.options)))
674 LoadOption(nodeConfig.options);
675 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !platform) ? 1 : 2); }
676 if(!mergeValues || configReplaces) { FinalizeLoading(); return; }
679 if(node.options && (mergeValues ? OptionCheck(node.options) : OptionSet(node.options)))
681 LoadOption(node.options);
682 if(!node.parent && !OptionCheck(node.options))
684 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
688 if(!setAttribs) { setAttribs = true; SetAttribs((node == currentNode && !config && !platform) ? 1 : 2); }
690 if(!mergeValues) { FinalizeLoading(); return; }
692 else if(!node.parent)
695 if(!setAttribs) { setAttribs = true; SetAttribs(0); }
696 if(!mergeValues) { FinalizeLoading(); return; }
703 class StringOptionBox : OptionBox<String>
707 bool NotifyModified(EditBox editBox)
709 ((OptionBox)editBox.id).Retrieve();
713 textHorzScroll = true;
716 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
718 String * string = (String*)((byte *)options + option);
719 if(*string) delete *string;
720 *string = CopyString(((EditBox)editor).contents);
723 void LoadOption(ProjectOptions options)
725 ((EditBox)editor).contents = options ? *(String*)((byte *)options + option) : "";
726 ((EditBox)editor).Deselect();
729 bool OptionCheck(ProjectOptions options)
731 String string = *(String*)((byte *)options + option);
732 return string && string[0];
735 void UnsetOption(ProjectOptions options)
737 delete *(String*)((byte *)options + option);
741 class PathOptionBox : OptionBox<String>
743 bool Window::EditBoxORB(int x, int y, Modifiers mods)
745 Window parent = this.parent;
746 x += clientStart.x + position.x;
747 y += clientStart.y + position.y;
748 return ((OptionBox)this).OptionBox_OnRightButtonDown(parent, x, y, mods);
753 typeExpected = directory, browseDialog = { };
754 editBox.OnRightButtonDown = (void *)EditBoxORB;
756 bool NotifyModified(PathBox pathBox)
758 FixPathOnPathBoxNotifyModified(pathBox);
759 ((OptionBox)pathBox.id).Retrieve();
764 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
766 String * string = (String*)((byte *)options + option);
767 String slashPath = ((PathBox)editor).slashPath;
768 if(*string) delete *string;
769 *string = CopyString(slashPath);//(slashPath && slashPath[0]) ? CopyString(slashPath) : null;
772 void LoadOption(ProjectOptions options)
774 ((PathBox)editor).path = options ? *(String*)((byte *)options + option) : "";
775 ((PathBox)editor).Deselect();
778 bool OptionCheck(ProjectOptions options)
780 String string = *(String*)((byte *)options + option);
781 return string && string[0];
784 void UnsetOption(ProjectOptions options)
786 delete *(String*)((byte *)options + option);
790 class MultiStringOptionBox : OptionBox<Array<String>>
795 caseSensitive = true;
797 virtual Array<String> GetStrings();
798 virtual void SetStrings(Array<String> value);
800 Array<String> tempStrings;
802 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
804 Array<String> newStrings = GetStrings();
805 Array<String> * strings = (Array<String>*)((byte *)options + option);
806 if(*strings) { strings->Free(); delete *strings; }
810 Iterator<String> it { newStrings };
812 FigureOutInherited();
816 Array<String> ts = tempStrings;
821 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
822 if(found && (!configReplaces || platform)) // ADDED || platform here...
832 if(!mergeValues || (configReplaces && isCfgOrPlt && !platform))
833 *strings = newStrings;
836 *strings = (newStrings && newStrings.count) ? newStrings : null;
837 if(newStrings && !newStrings.count) delete newStrings;
843 void LoadOption(ProjectOptions options)
847 Array<String> strings = options ? *((Array<String>*)((byte *)options + option) : null;
855 for(i : tempStrings; !(caseSensitive ? strcmp : strcmpi)(i, s)) { found = true; break; }
856 if(!found) tempStrings.Add(s);
862 SetStrings(options ? *(Array<String>*)((byte *)options + option) : null);
866 void FinalizeLoading()
870 SetStrings(tempStrings);
875 bool OptionSet(ProjectOptions options)
877 Array<String> strings = *(Array<String>*)((byte *)options + option);
878 if(mergeValues && !configReplaces)
880 return strings && strings.count;
883 return strings != null;
886 bool OptionCheck(ProjectOptions options)
888 Array<String> strings = *(Array<String>*)((byte *)options + option);
889 return strings && strings.count;
892 void UnsetOption(ProjectOptions options)
894 Array<String> * strings = (Array<String>*)((byte *)options + option);
895 if(*strings) { strings->Free(); delete *strings; }
899 class StringArrayOptionBox : MultiStringOptionBox
901 editor = StringListBox
903 bool NotifyModified(EditBox editBox)
905 ((OptionBox)editBox.id).Retrieve();
910 // NO VIRTUAL PROPERTIES YET...
911 Array<String> GetStrings() { return ((StringListBox)editor).strings; }
912 void SetStrings(Array<String> value) { ((StringListBox)editor).strings = value; }
915 class StringsArrayOptionBox : MultiStringOptionBox
925 bool NotifyModified(StringsBox stringsBox)
927 ((OptionBox)stringsBox.id).Retrieve();
932 Array<String> GetStrings() { return ((StringsBox)editor).strings; }
933 void SetStrings(Array<String> value) { ((StringsBox)editor).strings = value; }
936 bool eString_IsPathRelatedTo(char * path, char * to)
940 char rest[MAX_FILENAME];
941 char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION] = "";
942 char toPart[MAX_FILENAME], toRest[MAX_LOCATION] = "";
943 SplitDirectory(path, pathPart, pathRest);
944 SplitDirectory(to, toPart, toRest);
945 if(!fstrcmp(pathPart, toPart))
947 if(pathRest[0] && toRest[0])
949 SplitDirectory(pathRest, pathPart, pathRest);
950 SplitDirectory(toRest, toPart, toRest);
951 if(!fstrcmp(pathPart, toPart))
959 static void FixPathOnPathBoxNotifyModified(PathBox pathBox)
962 char path[MAX_LOCATION];
964 bool volumePath = false;
966 strcpy(path, pathBox.path);
967 TrimLSpaces(path, path);
968 TrimRSpaces(path, path);
969 MakeSystemPath(path);
971 if(path[0] && path[1] == ':')
978 char * chars = "*|:\",<>?";
979 char ch, * s = path, * o = path;
980 while((ch = *s++)) { if(!strchr(chars, ch)) *o++ = ch; }
984 if(len>1 && path[len-1] == DIR_SEP)
987 if(volumePath && path[0])
990 if(len && !(path[0] == '.' && (len == 1 || (len == 2 && path[1] == DIR_SEP) || (len > 1 && path[1] == '.'))))
992 char cwdBackup[MAX_LOCATION];
995 GetWorkingDir(cwdBackup, sizeof(cwdBackup));
996 ChangeWorkingDir(project.topNode.path);
1000 ChangeWorkingDir(cwdBackup);
1001 if(eString_IsPathRelatedTo(path, project.topNode.path))
1002 MakePathRelative(path, project.topNode.path, path);
1006 pathBox.path = path;
1009 class DirsArrayOptionBox : MultiStringOptionBox
1011 editor = DirectoriesBox
1013 bool NotifyModified(DirectoriesBox dirsBox)
1015 ((OptionBox)dirsBox.id).Retrieve();
1019 bool NotifyPathBoxModified(DirectoriesBox dirsBox, PathBox pathBox)
1021 FixPathOnPathBoxNotifyModified(pathBox);
1026 Array<String> GetStrings() { return ((DirectoriesBox)editor).strings; }
1027 void SetStrings(Array<String> value) { ((DirectoriesBox)editor).strings = value; }
1030 class BoolOptionBox : OptionBox<SetBool>
1036 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1038 ((OptionBox)button.id).Retrieve();
1043 bool OptionCheck(ProjectOptions options)
1045 return *(SetBool*)((byte *)options + option) == true;
1048 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1050 bool checked = ((Button)editor).checked;
1051 *(SetBool*)((byte *)options + option) = checked ? true :
1052 ((currentNode.parent || isCfgOrPlt) ? false : unset);
1055 void LoadOption(ProjectOptions options)
1057 ((Button)editor).checked = options && (*(SetBool*)((byte *)options + option) == true);
1061 class CheckBoxForEnumOptionBox : OptionBox
1067 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1069 ((OptionBox)button.id).Retrieve();
1072 for(slave = master.firstSlave; slave; slave = slave.nextSlave)
1074 if(eClass_IsDerived(slave._class, class(CheckBoxForEnumOptionBox)) &&
1075 slave != (Window)button.id &&
1076 ((OptionBox)slave).option == ((OptionBox)button.id).option)
1077 ((OptionBox)slave).Load();
1085 void LoadOption(ProjectOptions options)
1087 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1088 ((Button)editor).checked = value == enumValue;
1091 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1093 Button checkBox = (Button)editor;
1094 if(checkBox.checked)
1095 *(Z*)((byte *)options + option) = enumValue;
1099 class BuildBitDepthOptionBox : CheckBoxForEnumOptionBox<BuildBitDepth> { }
1101 class DropOptionBox : OptionBox
1105 bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods)
1107 ((OptionBox)dropBox.id).Retrieve();
1112 void LoadOption(ProjectOptions options)
1114 DropBox dropBox = (DropBox)editor;
1115 Z value = options ? *(Z*)((byte *)options + option) : (Z)0;
1116 dropBox.currentRow = value ? dropBox.FindRow((int64)value) : dropBox.firstRow;
1119 void RetrieveOption(ProjectOptions options, bool isCfgOrPlt)
1121 DropBox dropBox = (DropBox)editor;
1122 DataRow row = dropBox.currentRow;
1123 Z value = (Z)(row ? row.tag : 0);
1124 *(Z*)((byte *)options + option) = value;
1128 class TargetTypeDB : DropOptionBox<TargetTypes>
1134 row = ((DropBox)editor).AddRow();
1135 row.tag = TargetTypes::executable;
1136 row.SetData(null, $"Executable");
1138 row = ((DropBox)editor).AddRow();
1139 row.tag = TargetTypes::sharedLibrary;
1140 row.SetData(null, $"Shared Library");
1142 row = ((DropBox)editor).AddRow();
1143 row.tag = TargetTypes::staticLibrary;
1144 row.SetData(null, $"Static Library");
1147 bool OptionCheck(ProjectOptions options)
1149 TargetTypes value = *(TargetTypes*)((byte *)options + option);
1150 return value && value != executable;
1154 class OptimizationDB : DropOptionBox<OptimizationStrategy>
1159 row = ((DropBox)editor).AddRow();
1160 row.tag = OptimizationStrategy::none;
1161 row.SetData(null, $"None");
1163 row = ((DropBox)editor).AddRow();
1164 row.tag = OptimizationStrategy::speed;
1165 row.SetData(null, $"For Speed (-O2)");
1167 row = ((DropBox)editor).AddRow();
1168 row.tag = OptimizationStrategy::size;
1169 row.SetData(null, $"For Size (-Os)");
1172 bool OptionCheck(ProjectOptions options)
1174 OptimizationStrategy value = *(OptimizationStrategy*)((byte *)options + option);
1175 return value && value != none;
1179 class WarningsDB : DropOptionBox<WarningsOption>
1184 row = ((DropBox)editor).AddRow();
1185 row.tag = WarningsOption::normal;
1186 row.SetData(null, $"Normal");
1188 row = ((DropBox)editor).AddRow();
1189 row.tag = WarningsOption::none;
1190 row.SetData(null, $"None");
1192 row = ((DropBox)editor).AddRow();
1193 row.tag = WarningsOption::all;
1194 row.SetData(null, $"All");
1197 bool OptionCheck(ProjectOptions options)
1199 WarningsOption value = *(WarningsOption*)((byte *)options + option);
1200 return value && value != none;
1204 void DrawStipple(Surface surface, Size clientSize)
1208 int x2 = clientSize.w - 1;
1209 int y2 = clientSize.h - 1;
1210 if((x2 - x1) & 1) x2--;
1211 if((y2 - y1) & 1) y2--;
1213 surface.LineStipple(0x5555);
1214 surface.Rectangle(x1, y1, x2, y2);
1215 surface.LineStipple(0);
1218 class BuildTab : Tab
1221 background = formColor;
1224 ProjectNode backupNode;
1225 String activeConfigName;
1227 ProjectNode lastSelectedNode;
1229 property char * selectedConfigName
1235 SelectorButton button = (SelectorButton)configSelector.selectedButton;
1236 if(button && button.id)
1238 ProjectConfig config = (ProjectConfig)button.id;
1246 property char * selectedPlatformName
1252 SelectorButton button = (SelectorButton)platformSelector.selectedButton;
1253 if(button && button.id)
1255 Platform platform = (Platform)button.id;
1256 char * platformName = platform ? platform.OnGetString(0,0,0) : null; // all these platformName are leaking, no?
1257 return platformName;
1264 Label labelConfigurations
1266 this, anchor = { left = 8, top = 14 }, labeledWindow = configSelector;
1268 void OnRedraw(Surface surface)
1270 Label::OnRedraw(surface);
1271 if(labeledWindow.active) DrawStipple(surface, clientSize);
1274 SelectorBar configSelector
1276 this, text = $"Configurations: ", anchor = { left = 98, top = 8, right = 54 }; size = { 0, 26 };
1278 direction = horizontal, scrollable = true;
1280 bool OnKeyDown(Key key, unichar ch)
1284 ((BuildTab)parent).createConfig.NotifyClicked(parent, ((BuildTab)parent).createConfig, 0, 0, 0);
1289 ((BuildTab)parent).deleteConfig.NotifyClicked(parent, ((BuildTab)parent).deleteConfig, 0, 0, 0);
1292 return SelectorBar::OnKeyDown(key, ch);
1295 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1297 ((BuildTab)master).labelConfigurations.Update(null);
1304 parent = this, bevelOver = true, inactive = true;
1306 anchor = { top = 10, right = 31 };
1307 hotKey = altC, bitmap = BitmapResource { fileName = ":actions/docNew.png", alphaBlend = true };
1309 bool NotifyClicked(Button b, int x, int y, Modifiers mods)
1311 char tmp[MAX_F_STRING];
1312 ProjectConfig config;
1313 EditableSelectorButton button;
1315 FindUniqueConfigName("NewConfig", false, tmp);
1319 makingModified = true;
1320 compilingModified = true;
1321 linkingModified = true;
1322 name = CopyString(tmp);
1325 // objectsDirectory = /*CopyString(*/defaultObjDirExpression/*)*/;
1328 if(!project.topNode.configurations) project.topNode.configurations = { };
1329 project.topNode.configurations.Add(config);
1331 targetType = project.config.options.targetType;
1333 config.options.targetFileName = project.moduleName;
1334 config.options.targetDir.dir = "";
1335 config.options.objectsDirectory = defaultObjDirExpression);
1336 config.options.debug = true;
1337 config.options.optimization = none;
1338 config.options.warnings = all;
1343 configSelector, renameable = true, master = this, text = config.name, id = (int64)config;
1344 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1347 configSelector.Select(button);
1348 modifiedDocument = true;
1352 /*Button duplicateConfig
1354 parent = this, bevelOver = true, inactive = true;
1356 anchor = { top = 10, right = 31 };
1357 hotKey = altU, bitmap = BitmapResource { fileName = ":actions/editCopy.png", alphaBlend = true };
1361 parent = this, bevelOver = true, inactive = true;
1363 anchor = { top = 10, right = 8 };
1364 hotKey = altD, bitmap = BitmapResource { fileName = ":actions/delete2.png", alphaBlend = true };
1366 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1370 String title = PrintString($"Delete ", config.name, $" Configuration");
1371 String msg = PrintString($"Are you sure you wish to delete the ", config.name, $" configuration?");
1372 if(MessageBox { type = okCancel, text = title, contents = msg }.Modal() == ok)
1374 Iterator<Window> it { configSelector.controls };
1375 ProjectConfig configToDelete = config;
1379 SelectorButton button = (SelectorButton)it.data;
1380 if((ProjectConfig)button.id == config)
1382 button.visible = false;
1387 button = (SelectorButton)it.data;
1388 config = (ProjectConfig)button.id;
1389 configSelector.Select(button);
1395 SelectorButton button = configSelector.FindButtonByID((int64)configToDelete);
1397 configSelector.RemoveButton(button);
1399 project.topNode.DeleteConfig(configToDelete);
1401 modifiedDocument = true;
1410 Label labelPlatforms
1412 this, anchor = { left = 8, top = 44 }, labeledWindow = platformSelector;
1414 void OnRedraw(Surface surface)
1416 Label::OnRedraw(surface);
1417 if(labeledWindow.active) DrawStipple(surface, clientSize);
1420 SelectorBar platformSelector
1422 this, text = $"Platforms: ", anchor = { left = 64, top = 38, right = 54 }; size = { 0, 26 };
1424 direction = horizontal, scrollable = true;
1426 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
1428 ((BuildTab)master).labelPlatforms.Update(null);
1433 TabControl buildTabControl
1435 this, background = formColor, anchor = { left = 8, top = 64, right = 8, bottom = 8 };
1436 curTab = compilerTab;
1438 CompilerTab compilerTab { this, tabControl = buildTabControl };
1439 LinkerTab linkerTab { this, tabControl = buildTabControl };
1440 BuilderTab builderTab { this, tabControl = buildTabControl };
1443 this, font = { font.faceName, font.size, italic = true }, stayOnTop = true,
1444 text = $"(Right click or press Ctrl-Del to revert an option to inherited value)", anchor = { top = 72, right = 16 }
1447 void FindUniqueConfigName(char * baseName, bool startWithNumber, char * output)
1450 char tmp[MAX_F_STRING];
1452 sprintf(tmp, "%s%d", baseName, num);
1454 strcpy(tmp, baseName);
1457 ProjectConfig config = null;
1458 for(c : project.topNode.configurations)
1459 { // TOFIX: Error when omitting these brackets, c not found
1460 if(c.name && !strcmp(c.name, tmp))
1469 sprintf(tmp, "%s%d", baseName, num);
1474 strcpy(output, tmp);
1477 bool PlatformClicked(Button clickedButton, int x, int y, Modifiers mods)
1479 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1481 platform = (Platform)clickedButton.id;
1483 // Load Settings Into Dialog
1484 compilerTab.LoadSettings();
1485 linkerTab.LoadSettings();
1486 builderTab.LoadSettings();
1489 buildTabControl.Activate();
1491 if(compilerTab.rightPaneHeader.visible)
1492 compilerTab.rightPaneHeader.Update(null);
1493 ((ProjectSettings)master).UpdateDialogTitle();
1500 platformSelector.DestroyChildren();
1501 configSelector.DestroyChildren();
1503 delete activeConfigName;
1506 bool ConfigOnRename(EditableSelectorButton button, char * * oldName, char * * newName)
1511 for(c = 0; (ch = (*newName)[c]); c++)
1513 if(ch == '_' || isalpha(ch) || (isdigit(ch) && d))
1514 (*newName)[d++] = ch;
1520 for(c : project.topNode.configurations; c != config)
1522 if(!strcmpi(c.name, *newName))
1528 if(found || !(*newName)[0])
1530 char tmp[MAX_F_STRING];
1531 char * tmpName = config.name;
1533 FindUniqueConfigName("NewConfig", false, tmp);
1534 config.name = tmpName;
1536 *newName = CopyString(tmp);
1540 if(activeConfigName && !strcmp(activeConfigName, *oldName))
1542 delete activeConfigName;
1543 activeConfigName = CopyString(*newName);
1546 project.topNode.RenameConfig(config.name, *newName);
1548 modifiedDocument = true;
1552 bool ConfigClicked(Button clickedButton, int x, int y, Modifiers mods)
1554 if(!eClass_IsDerived(clickedButton._class, class(EditableSelectorButton)) || !((EditableSelectorButton)clickedButton).editBox)
1556 config = (ProjectConfig)clickedButton.id;
1558 // Load Settings Into Dialog
1559 compilerTab.LoadSettings();
1560 linkerTab.LoadSettings();
1561 builderTab.LoadSettings();
1563 deleteConfig.disabled = (clickedButton._class == class(SelectorButton));
1566 buildTabControl.Activate();
1568 compilerTab.fileList.Update(null);
1569 if(compilerTab.rightPaneHeader.visible)
1570 compilerTab.rightPaneHeader.Update(null);
1571 ((ProjectSettings)master).UpdateDialogTitle();
1576 void SelectNode(ProjectNode node, bool ignoreAsLastSelection)
1578 if(node != currentNode)
1580 Window ac = compilerTab.rightPane.activeChild;
1581 bool prevNodeRes = currentNode ? currentNode.isInResources : false;
1584 if(!node) node = project.topNode;
1586 newNodeRes = node.isInResources;
1589 if(!ignoreAsLastSelection)
1590 lastSelectedNode = node;
1592 ((ProjectSettings)master).UpdateDialogTitle();
1593 if(node.type == project)
1595 compilerTab.rightPaneHeader.visible = false;
1599 compilerTab.rightPaneHeader.id = (int64)node;
1600 compilerTab.rightPaneHeader.Update(null);
1601 compilerTab.rightPaneHeader.visible = true;
1605 DataRow row = compilerTab.fileList.FindSubRow((int64)currentNode);
1608 compilerTab.fileList.currentRow = row;
1609 while((row = row.parent))
1610 row.collapsed = false;
1614 if(prevNodeRes != newNodeRes)
1616 compilerTab.labelObjDir.visible = !newNodeRes;
1617 compilerTab.objDir.visible = !newNodeRes;
1618 compilerTab.excludeFromBuild.visible = !newNodeRes;
1619 compilerTab.labelPreprocessorDefs.visible = !newNodeRes;
1620 compilerTab.preprocessorDefs.visible = !newNodeRes;
1621 compilerTab.labelDefaultNameSpace.visible = !newNodeRes;
1622 compilerTab.defaultNameSpace.visible = !newNodeRes;
1623 compilerTab.strictNameSpaces.visible = !newNodeRes;
1624 compilerTab.memoryGuard.visible = !newNodeRes;
1625 compilerTab.noLineNumbers.visible = !newNodeRes;
1626 compilerTab.debug.visible = !newNodeRes;
1627 compilerTab.labelWarnings.visible = !newNodeRes;
1628 compilerTab.warnings.visible = !newNodeRes;
1629 compilerTab.profiling.visible = !newNodeRes;
1630 compilerTab.labelOptimization.visible = !newNodeRes;
1631 compilerTab.optimization.visible = !newNodeRes;
1632 compilerTab.fastMath.visible = !newNodeRes;
1633 compilerTab.labelIncludeDirs.visible = !newNodeRes;
1634 compilerTab.includeDirs.visible = !newNodeRes;
1637 if(node == project.topNode)
1639 compilerTab.objDir.visible = true;
1640 compilerTab.labelObjDir.visible = true;
1642 compilerTab.excludeFromBuild.visible = false;
1646 compilerTab.objDir.visible = false;
1647 compilerTab.labelObjDir.visible = false;
1649 compilerTab.excludeFromBuild.visible = (node != project.resNode);
1652 // Load Settings Into Dialog
1653 compilerTab.LoadSettings();
1654 linkerTab.LoadSettings();
1655 builderTab.LoadSettings();
1661 if(ac == compilerTab.excludeFromBuild.editor)
1662 ac = compilerTab.objDir.editor;
1663 else if(compilerTab.excludeFromBuild.editor.visible)
1664 ac = compilerTab.excludeFromBuild.editor;
1671 void CreateConfigButtons()
1673 SelectorButton commonButton;
1675 // Create Config Buttons
1676 commonButton = SelectorButton
1678 configSelector, master = this, text = $"Common", id = (int64)null; font = { font.faceName, font.size, true };
1680 NotifyClicked = ConfigClicked;
1685 if(project.topNode.configurations)
1687 for(c : project.topNode.configurations)
1689 EditableSelectorButton button
1691 configSelector, master = this, renameable = true, text = c.name, id = (int64)c;
1692 NotifyClicked = ConfigClicked, OnRename = ConfigOnRename;
1701 SelectorButton button;
1703 activeConfigName = project.config ? CopyString(project.config.name) : null;
1705 compilerTab.AddNode(project.topNode, null);
1707 CreateConfigButtons();
1709 platformButton = button =
1711 platformSelector, master = this, text = $"Common", id = 0; font = { font.faceName, font.size, true };
1712 NotifyClicked = PlatformClicked; checked = true;
1717 for(p = (Platform)1; p < Platform::enumSize; p++)
1719 SelectorButton button
1721 platformSelector, master = this, text = p.OnGetString(0,0,0), id = (int64)p;
1722 NotifyClicked = PlatformClicked;
1726 SelectorButton platformButton;
1730 // Backup Current Settings
1731 backupNode = project.topNode.Backup();
1733 buildTabControl.Activate();
1736 Iterator<Window> it { configSelector.controls };
1739 SelectorButton configButton = (SelectorButton)it.data;
1740 ProjectConfig buttonConfig = (ProjectConfig)configButton.id;
1741 if(buttonConfig == project.config)
1743 configButton.Activate();
1744 configButton.checked = true;
1745 ConfigClicked(configButton, 0, 0, (Modifiers)null);
1752 platformButton.MakeActive();
1753 platformButton = null;
1762 lastSelectedNode = null;
1764 project.config = null;
1766 /* // THIS IS NOW AUTOMATED WITH A project CHECK IN ProjectNode
1767 project.configurations = project.topNode.configurations;
1768 project.platforms = project.topNode.platforms;
1769 project.options = project.topNode.options;
1772 if(project.topNode.configurations)
1774 for(c : project.topNode.configurations)
1776 if(!strcmpi(c.name, activeConfigName))
1785 List<ProjectConfig> configs = project.topNode.configurations;
1786 if(configs && configs.count)
1787 project.config = configs[0];
1790 ide.UpdateToolBarActiveConfigs(false);
1793 void RevertChanges()
1795 String configName = config ? CopyString(config.name) : null;
1797 // Revert to saved project options
1798 project.topNode.Revert(backupNode);
1800 configSelector.DestroyChildren();
1801 CreateConfigButtons();
1803 // Reselect Configuration
1806 Iterator<Window> it { configSelector.controls };
1809 Button button = (Button)it.data;
1810 ProjectConfig c = (ProjectConfig)button.id;
1811 if(c && !strcmp(c.name, configName))
1815 button.checked = true;
1816 ConfigClicked(button, 0,0, 0);
1822 SelectNode(project.topNode, false);
1827 bool OnClose(bool parentClosing)
1829 if(modifiedDocument)
1831 DialogResult diagRes = MessageBox
1833 type = yesNoCancel, master = ide,
1834 text = $"Save changes to project settings?",
1835 contents = $"Would you like to save changes made to the build options?"
1839 if(diagRes == cancel)
1843 project.MarkChanges(backupNode);
1844 project.topNode.modified = true;
1845 ide.projectView.modifiedDocument = true;
1846 ide.UpdateToolBarActiveConfigs(false);
1847 ide.projectView.Update(null);
1849 modifiedDocument = false;
1855 class CompilerTab : Tab
1857 background = formColor;
1860 Window leftPane { this, size = { 180 }, anchor = { left = 0, top = 0, bottom = 0 }, background = formColor };
1862 Label labelFileList { leftPane, this, position = { 8, 8 }, labeledWindow = fileList };
1865 leftPane, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
1866 // THIS WOULD BE EVEN MORE FUN: multiSelect = true,
1867 fullRowSelect = false, collapseControl = true, treeBranches = true;
1868 alwaysHighLight = true;
1869 selectionColor = unfocusedSelectorColor;
1871 anchor = Anchor { left = 8, top = 24, right = 4, bottom = 8 };
1874 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
1876 BuildTab buildTab = (BuildTab)master;
1877 ProjectNode node = (ProjectNode)row.tag;
1878 buildTab.SelectNode(node, false);
1882 void OnRedraw(Surface surface)
1884 ide.projectView.drawingInProjectSettingsDialog = true;
1885 ListBox::OnRedraw(surface);
1886 ide.projectView.drawingInProjectSettingsDialog = false;
1889 bool NotifyActivate(Window window, bool active, Window previous)
1893 //subclass(Skin) skinClass = (subclass(Skin))eSystem_FindClass(app, app.skin);
1894 fileList.selectionColor = Color { 10, 36, 106 }; //skinClass.selectionColor; // darkBlue;
1896 else if(fileList.currentRow)
1898 DataRow currentRow = fileList.currentRow;
1899 //int headerSize = ((fileList.style.header) ? fileList.rowHeight : 0);
1900 int height = fileList.clientSize.h + 1;// - fileList.headerSize;
1901 fileList.selectionColor = unfocusedSelectorColor;
1902 if(currentRow && currentRow.index * fileList.rowHeight > fileList.scroll.y + height - fileList.rowHeight)
1903 fileList.SetScrollPosition(fileList.scroll.x, currentRow.index * fileList.rowHeight - height + fileList.rowHeight);
1904 else if(!currentRow || currentRow.index * fileList.rowHeight < fileList.scroll.y)
1905 fileList.SetScrollPosition(fileList.scroll.x, currentRow ? currentRow.index * fileList.rowHeight : 0);
1915 this, anchor = { left = 196, top = 0, right = 0, bottom = 0 }, background = formColor, tabCycle = true;
1918 Window rightPaneHeader
1920 rightPane, this, size = { h = 21 }, anchor = { left = 0, top = 0, right = 0 }, background = Color { 70, 96, 166 };//0x0F3F66;
1921 foreground = white; visible = false;
1923 void OnRedraw(Surface surface)
1927 ide.projectView.drawingInProjectSettingsDialogHeader = true;
1928 ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(ProjectNode)._vTbl[__ecereVMethodID_class_OnDisplay])(class(ProjectNode),
1929 (void *)id, surface, 8, 2, clientSize.w, ide.projectView, Alignment::left, DataDisplayFlags { selected = true });
1930 ide.projectView.drawingInProjectSettingsDialogHeader = false;
1935 PaneSplitter splitter
1937 this, leftPane = leftPane, rightPane = rightPane, split = 188
1940 Label labelObjDir { rightPane, this, position = { 8, 8 }, labeledWindow = objDir };
1941 PathOptionBox objDir
1943 rightPane, this, size = { 250, 22 }, anchor = { left = 8, top = 24, right = 8 };
1944 text = $"Intermediate Objects Directory", hotKey = altJ, option = OPTION(objectsDirectory);
1947 BoolOptionBox excludeFromBuild
1949 rightPane, this, position = { 8, 28 },
1950 text = $"Exclude from Build", visible = false, option = OPTION(excludeFromBuild);
1953 Label labelPreprocessorDefs { rightPane, this, position = { 8, 50 }, labeledWindow = preprocessorDefs };
1954 StringArrayOptionBox preprocessorDefs
1956 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
1957 text = $"Preprocessor Definitions", hotKey = altD, option = OPTION(preprocessorDefinitions);
1960 Label labelDefaultNameSpace { rightPane, this, position = { 8, 92 }, labeledWindow = defaultNameSpace };
1961 StringOptionBox defaultNameSpace
1963 rightPane, this, size = { 160, 22 }, position = { 8, 108 };
1964 text = $"Default Name Space", option = OPTION(defaultNameSpace);
1966 BoolOptionBox strictNameSpaces
1968 rightPane, this, position = { 172, 112 },
1969 text = $"Strict Name Spaces", option = OPTION(strictNameSpaces);
1972 BoolOptionBox fastMath
1974 rightPane, this, position = { 316, 112 },
1975 text = $"Fast Math", option = OPTION(fastMath);
1978 BoolOptionBox memoryGuard
1980 rightPane, this, position = { 8, 154 };
1981 text = $"MemoryGuard", hotKey = altM, option = OPTION(memoryGuard);
1984 Label labelWarnings { rightPane, position = { 116, 138 }, labeledWindow = warnings };
1987 rightPane, this, position = { 116, 154 };
1988 text = $"Warnings", hotKey = altW, option = OPTION(warnings);
1991 Label labelOptimization { rightPane, position = { 220, 138 }, labeledWindow = optimization };
1992 OptimizationDB optimization
1994 rightPane, this, position = { 220, 154 }, size = { 120, 22 };
1995 text = $"Optimization", hotKey = altO, option = OPTION(optimization);
2000 rightPane, this, position = { 8, 188 };
2001 text = $"Debuggable", hotKey = altG, option = OPTION(debug);
2004 BoolOptionBox profiling
2006 rightPane, this, position = { 116, 188 };
2007 text = $"Profiling Data", hotKey = altP, option = OPTION(profile);
2010 BoolOptionBox noLineNumbers
2012 rightPane, this, position = { 220, 188 };
2013 text = $"No Line Numbers", hotKey = altN, option = OPTION(noLineNumbers);
2016 Label labelCompilerOptions { rightPane, this, position = { 8, 208 }, labeledWindow = compilerOptions };
2017 StringArrayOptionBox compilerOptions
2019 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 224, right = 8 };
2020 text = $"Compiler Options", hotKey = altO, option = OPTION(compilerOptions);
2021 configReplaces = true;
2024 Label labelIncludeDirs { includeDirs.editor, labeledWindow = includeDirs, position = { 0, 6 }; };
2025 DirsArrayOptionBox includeDirs
2027 rightPane, this, size = { 290, 22 }, anchor = { left = 8, top = 250, right = 8, bottom = 8 };
2028 text = $"Additional Include Directories", hotKey = altI, option = OPTION(includeDirs);
2033 fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false,
2034 userData = null /* Now set in the ProjectNode directly to know we're in ProjectSettings Dialog -- ide.projectView*/ });
2039 BuildTab buildTab = (BuildTab)master;
2040 buildTab.SelectNode(buildTab.lastSelectedNode, true);
2044 void AddNode(ProjectNode node, DataRow addTo)
2046 DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
2048 row.tag = (int64)node;
2050 row.SetData(null, node);
2052 if(node.files && node.files.first && node.parent &&
2053 !(!node.parent.parent &&
2054 (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") ||
2055 !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
2056 row.collapsed = true;
2057 else if(node.type == folder)
2058 node.icon = openFolder;
2062 for(child : node.files)
2063 AddNode(child, row);
2070 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2071 if(eClass_IsDerived(ob._class, class(OptionBox)))
2074 if(activeChild && activeChild.active)
2076 Window control = activeChild;
2077 control.Deactivate();
2084 objDir.editor.Activate();
2089 class LinkerTab : Tab
2091 background = formColor;
2094 Label labelTargetName { this, position = { 8, 8 }, labeledWindow = targetName };
2095 StringOptionBox targetName
2097 this, position = { 8, 24 }, size = { 200, 22 };
2098 text = $"Target Name", hotKey = altN, option = OPTION(targetFileName);
2101 Label labelTargetType { this, position = { 216, 8 }, labeledWindow = targetType };
2102 TargetTypeDB targetType
2104 this, position = { 216, 24 }, size = { 120, 22 };
2105 text = $"Target Type", hotKey = altT, option = OPTION(targetType);
2108 Label labelTargetDirectory { this, position = { 344, 8 }, labeledWindow = targetDirectory };
2109 PathOptionBox targetDirectory
2111 this, size = { 270, 22 }, anchor = { left = 344, top = 24, right = 8 };
2112 hotKey = altR, text = $"Target Directory", option = OPTION(targetDirectory);
2115 Label labelLibraries { this, position = { 8, 50 }, labeledWindow = libraries };
2116 StringArrayOptionBox libraries
2118 this, size = { 290, 22 }, anchor = { left = 8, top = 66, right = 8 };
2119 text = $"Additional Libraries", hotKey = altL, option = OPTION(libraries);
2120 configReplaces = true;
2123 Label labelLinkerOptions { this, position = { 8, 92 }, labeledWindow = linkerOptions };
2124 StringArrayOptionBox linkerOptions
2126 this, size = { 290, 22 }, anchor = { left = 8, top = 108, right = 8 };
2127 text = $"Linker Options", hotKey = altO, option = OPTION(linkerOptions);
2128 configReplaces = true;
2131 BoolOptionBox console
2133 this, position = { 8, 138 };
2134 text = $"Console Application", hotKey = altC, option = OPTION(console);
2137 BoolOptionBox compress
2139 this, position = { 8, 162 };
2140 text = $"Compress", hotKey = altW, option = OPTION(compress);
2143 Label labelLibraryDirs { libraryDirs.editor, labeledWindow = libraryDirs, position = { 0, 6 }; };
2144 DirsArrayOptionBox libraryDirs
2146 this, size = { 290, 22 }, anchor = { left = 8, top = 182, right = 8, bottom = 8 };
2147 text = $"Additional Library Directories", hotKey = altY, option = OPTION(libraryDirs);
2152 ((BuildTab)master).SelectNode(project.topNode, true);
2159 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2160 if(eClass_IsDerived(ob._class, class(OptionBox)))
2162 compress.disabled = (config && config.options && config.options.debug == true) || project.topNode.options.debug == true;
2164 if(activeChild && activeChild.active)
2166 Window control = activeChild;
2167 control.Deactivate();
2173 class BuilderTab : Tab
2175 background = formColor;
2178 Label labelPrebuildCommands { prebuildCommands.editor, labeledWindow = prebuildCommands, position = { 0, 6 }; };
2179 StringsArrayOptionBox prebuildCommands
2181 this, size = { 290, 100 }, anchor = { left = 8, top = 8, right = 8, bottom = 0.5 };
2182 text = $"Pre-build Commands", hotKey = altE, option = OPTION(prebuildCommands);
2185 Label labelPostbuildCommands { postbuildCommands.editor, labeledWindow = postbuildCommands, position = { 0, 6 }; };
2186 StringsArrayOptionBox postbuildCommands
2188 this, size = { 290 }, anchor = { left = 8, top = 0.5, right = 8, bottom = 8 };
2189 text = $"Post-build Commands", hotKey = altT, option = OPTION(postbuildCommands);
2194 bool disabled = strlen(((BuildTab)master).selectedPlatformName) > 0;
2196 for(ob = (OptionBox)firstSlave; ob; ob = (OptionBox)ob.nextSlave)
2197 if(eClass_IsDerived(ob._class, class(OptionBox)))
2200 if(activeChild && activeChild.active)
2202 Window control = activeChild;
2203 control.Deactivate();