BuildPropertiesDialog.bf 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using System;
  2. using System.Collections;
  3. using Beefy.widgets;
  4. using Beefy.theme.dark;
  5. using Beefy.theme;
  6. using Beefy.gfx;
  7. namespace IDE.ui
  8. {
  9. class BuildPropertiesDialog : TargetedPropertiesDialog
  10. {
  11. protected class DistinctOptionBuilder
  12. {
  13. BuildPropertiesDialog mDialog;
  14. public this(BuildPropertiesDialog dialog)
  15. {
  16. mDialog = dialog;
  17. }
  18. class TypeOptionsEntry
  19. {
  20. public String mConfigName;
  21. public String mPlatformName;
  22. public List<DistinctBuildOptions> mPropTargets = new .() ~ delete _;
  23. }
  24. List<String> mTypeOptionsNames = new .() ~ delete _;
  25. Dictionary<String, TypeOptionsEntry> mTypeOptionsDict = new .() ~ delete _;
  26. public int mPropCount;
  27. public void Add(List<DistinctBuildOptions> distinctBuildOptions)
  28. {
  29. int propIdx = mPropCount;
  30. mPropCount++;
  31. for (int typeOptionIdx < distinctBuildOptions.Count)
  32. {
  33. var typeOptions = distinctBuildOptions[typeOptionIdx];
  34. if (typeOptions.mCreateState == .Deleted)
  35. continue;
  36. String* keyPtr;
  37. TypeOptionsEntry* typeOptionsPtr;
  38. TypeOptionsEntry typeOptionsEntry;
  39. if (mTypeOptionsDict.TryAdd(typeOptions.mFilter, out keyPtr, out typeOptionsPtr))
  40. {
  41. mTypeOptionsNames.Add(typeOptions.mFilter);
  42. typeOptionsEntry = new TypeOptionsEntry();
  43. *typeOptionsPtr = typeOptionsEntry;
  44. }
  45. else
  46. {
  47. typeOptionsEntry = *typeOptionsPtr;
  48. }
  49. typeOptionsEntry.mConfigName = mDialog.[Friend]mConfigNames[propIdx / mDialog.[Friend]mPlatformNames.Count];
  50. typeOptionsEntry.mPlatformName = mDialog.[Friend]mPlatformNames[propIdx % mDialog.[Friend]mPlatformNames.Count];
  51. typeOptionsEntry.mPropTargets.Add(typeOptions);
  52. }
  53. }
  54. public void Finish()
  55. {
  56. var root = (DarkListViewItem)mDialog.[Friend]mPropPage.mPropertiesListView.GetRoot();
  57. let configNames = mDialog.[Friend]mConfigNames;
  58. let platformNames = mDialog.[Friend]mPlatformNames;
  59. for (var typeOptionsName in mTypeOptionsNames)
  60. {
  61. var typeOptionsEntry = mTypeOptionsDict[typeOptionsName];
  62. var prevPropTargets = mDialog.[Friend]mCurPropertiesTargets;
  63. mDialog.[Friend]mCurPropertiesTargets = null;
  64. defer { mDialog.[Friend]mCurPropertiesTargets = prevPropTargets; }
  65. mDialog.[Friend]mCurPropertiesTargets = scope Object[typeOptionsEntry.mPropTargets.Count];
  66. for (int i < typeOptionsEntry.mPropTargets.Count)
  67. mDialog.[Friend]mCurPropertiesTargets[i] = typeOptionsEntry.mPropTargets[i];
  68. String label = scope .("Distinct Build Options");
  69. if (typeOptionsEntry.mPropTargets.Count < configNames.Count * platformNames.Count)
  70. {
  71. if (typeOptionsEntry.mPropTargets.Count > 1)
  72. label.Append(" <Multiple>");
  73. else if ((configNames.Count > 1) && (platformNames.Count > 1))
  74. label.AppendF(" ({0}/{1})", configNames[0], platformNames[1]);
  75. else if (configNames.Count > 1)
  76. label.AppendF(" ({0})", configNames[0]);
  77. else
  78. label.AppendF(" ({0})", platformNames[0]);
  79. }
  80. let (category, propEntry) = mDialog.AddPropertiesItem(root, label, "mFilter");
  81. mDialog.SetupDistinctBuildOptions(propEntry);
  82. mDialog.AddDistinctBuildOptions(category, -1, true);
  83. delete typeOptionsEntry;
  84. }
  85. }
  86. }
  87. protected List<Object> mDeferredDeleteList = new .() ~
  88. {
  89. for (let obj in _)
  90. {
  91. delete obj;
  92. }
  93. delete _;
  94. };
  95. protected void AddDistinctBuildOptions(DarkListViewItem category, int typeOptionIdx, bool isNew)
  96. {
  97. String optionsName = "";
  98. String typeName = scope String();
  99. if (!isNew)
  100. {
  101. typeName.Clear(); typeName.Append(optionsName, "mFilter");
  102. let propEntry = SetupPropertiesItem(category, "Filter", typeName);
  103. SetupDistinctBuildOptions(propEntry);
  104. }
  105. typeName.Clear(); typeName.Append(optionsName, "mBfSIMDSetting");
  106. AddPropertiesItem(category, "SIMD Instructions", typeName);
  107. typeName.Clear(); typeName.Append(optionsName, "mBfOptimizationLevel");
  108. AddPropertiesItem(category, "Optimization Level", typeName);
  109. typeName.Clear(); typeName.Append(optionsName, "mEmitDebugInfo");
  110. AddPropertiesItem(category, "Debug Info", typeName);
  111. typeName.Clear(); typeName.Append(optionsName, "mRuntimeChecks");
  112. AddPropertiesItem(category, "Runtime Checks", typeName,
  113. scope String[] ( "No", "Yes" ));
  114. typeName.Clear(); typeName.Append(optionsName, "mEmitDynamicCastCheck");
  115. AddPropertiesItem(category, "Dynamic Cast Check", typeName,
  116. scope String[] ( "No", "Yes" ));
  117. typeName.Clear(); typeName.Append(optionsName, "mEmitObjectAccessCheck");
  118. AddPropertiesItem(category, "Object Access Check", typeName,
  119. scope String[] ( "No", "Yes" ));
  120. typeName.Clear(); typeName.Append(optionsName, "mArithmeticCheck");
  121. AddPropertiesItem(category, "Arithmetic Check", typeName,
  122. scope String[] ( "No", "Yes" ));
  123. typeName.Clear(); typeName.Append(optionsName, "mAllocStackTraceDepth");
  124. AddPropertiesItem(category, "Alloc Stack Trace Depth", typeName);
  125. let (reflectItem, ?) = AddPropertiesItem(category, "Reflect");
  126. typeName.Clear(); typeName.Append(optionsName, "mReflectAlwaysInclude");
  127. AddPropertiesItem(reflectItem, "Always Include", typeName);
  128. typeName.Clear(); typeName.Append(optionsName, "mReflectBoxing");
  129. AddPropertiesItem(reflectItem, "Dynamic Boxing", typeName,
  130. scope String[] ( "No", "Yes" ));
  131. typeName.Clear(); typeName.Append(optionsName, "mReflectStaticFields");
  132. AddPropertiesItem(reflectItem, "Static Fields", typeName,
  133. scope String[] ( "No", "Yes" ));
  134. typeName.Clear(); typeName.Append(optionsName, "mReflectNonStaticFields");
  135. AddPropertiesItem(reflectItem, "Non-Static Fields", typeName,
  136. scope String[] ( "No", "Yes" ));
  137. typeName.Clear(); typeName.Append(optionsName, "mReflectStaticMethods");
  138. AddPropertiesItem(reflectItem, "Static Methods", typeName,
  139. scope String[] ( "No", "Yes" ));
  140. typeName.Clear(); typeName.Append(optionsName, "mReflectNonStaticMethods");
  141. AddPropertiesItem(reflectItem, "Non-Static Methods", typeName,
  142. scope String[] ( "No", "Yes" ));
  143. typeName.Clear(); typeName.Append(optionsName, "mReflectConstructors");
  144. AddPropertiesItem(reflectItem, "Constructors", typeName,
  145. scope String[] ( "No", "Yes" ));
  146. typeName.Clear(); typeName.Append(optionsName, "mReflectMethodFilter");
  147. AddPropertiesItem(reflectItem, "Method Filter", typeName);
  148. category.Open(true, true);
  149. }
  150. protected virtual Object[] PhysAddNewDistinctBuildOptions()
  151. {
  152. return null;
  153. }
  154. protected void AddNewDistinctBuildOptions()
  155. {
  156. var root = (DarkListViewItem)mPropPage.mPropertiesListView.GetRoot();
  157. var (category, propEntry) = AddPropertiesItem(root, "Distinct Build Options");
  158. var subItem = (DarkListViewItem)category.CreateSubItem(1);
  159. subItem.mTextColor = Color.Mult(DarkTheme.COLOR_TEXT, 0xFFC0C0C0);
  160. subItem.Label = "<Add New>...";
  161. subItem.mOnMouseDown.Add(new (evt) =>
  162. {
  163. if (category.GetChildCount() != 0)
  164. {
  165. return;
  166. }
  167. subItem.Label = "";
  168. let typeOptionsTargets = PhysAddNewDistinctBuildOptions();
  169. defer delete typeOptionsTargets;
  170. var prevTargets = mCurPropertiesTargets;
  171. defer { mCurPropertiesTargets = prevTargets; }
  172. mCurPropertiesTargets = typeOptionsTargets;
  173. AddDistinctBuildOptions(category, -1, false);
  174. AddNewDistinctBuildOptions();
  175. });
  176. category.mIsBold = true;
  177. category.mTextColor = cHeaderColor;
  178. }
  179. protected void DeleteDistinctBuildOptions(DarkListViewItem listViewItem)
  180. {
  181. mPropPage.mPropEntries.TryGetValue(listViewItem, var propEntries);
  182. if (propEntries == null)
  183. return;
  184. for (var propEntry in propEntries)
  185. {
  186. if (@propEntry == 0)
  187. {
  188. propEntry.mListViewItem.mParentItem.RemoveChildItem(propEntry.mListViewItem, false);
  189. mDeferredDeleteList.Add(propEntry.mListViewItem);
  190. }
  191. propEntry.mListViewItem = null;
  192. var typeOptions = (DistinctBuildOptions)propEntry.mTarget;
  193. typeOptions.mCreateState = .Deleted;
  194. }
  195. }
  196. protected void DeleteDistinctBuildOptions()
  197. {
  198. List<PropEntry> typeOptionsEntries = scope .();
  199. for (var propEntryKV in mPropPage.mPropEntries)
  200. {
  201. var propEntry = propEntryKV.value[0];
  202. if (propEntry.mPropertyName == "mFilter")
  203. {
  204. if (propEntry.mListViewItem != null)
  205. typeOptionsEntries.Add(propEntry);
  206. }
  207. }
  208. for (var propEntry in typeOptionsEntries)
  209. DeleteDistinctBuildOptions(propEntry.mListViewItem);
  210. }
  211. protected void UpdateDistinctBuildOptions(PropEntry propEntry)
  212. {
  213. if (propEntry.mListViewItem == null)
  214. return;
  215. var typeNames = propEntry.mCurValue.Get<String>();
  216. var subItem = (DarkListViewItem)propEntry.mListViewItem.GetSubItem(1);
  217. if ((typeNames.IsEmpty) || (typeNames == propEntry.mNotSetString))
  218. {
  219. subItem.Label = propEntry.mNotSetString;
  220. subItem.mTextColor = 0xFFC0C0C0;
  221. }
  222. else
  223. {
  224. bool isValid = true;
  225. for (var typeName in typeNames.Split(';'))
  226. {
  227. if (!typeNames.StartsWith("@"))
  228. {
  229. while (!typeName.IsEmpty)
  230. {
  231. if ((typeName[0] != ':') && (!typeName[0].IsWhiteSpace))
  232. break;
  233. typeName.RemoveFromStart(1);
  234. }
  235. if (!gApp.mBfResolveCompiler.VerifyTypeName(scope String(typeName), -1))
  236. isValid = false;
  237. }
  238. }
  239. subItem.mTextColor = isValid ? 0xFFFFFFFF : 0xFFFF8080;
  240. propEntry.mColorOverride = subItem.mTextColor;
  241. }
  242. }
  243. protected bool ApplyDistinctBuildOptions(List<DistinctBuildOptions> distinctBuildOptions, bool apply)
  244. {
  245. bool appliedChange = false;
  246. for (let typeOptions in distinctBuildOptions)
  247. {
  248. if (typeOptions.mCreateState == .Normal)
  249. continue;
  250. if (((apply) && (typeOptions.mCreateState == .New)) ||
  251. ((!apply) && (typeOptions.mCreateState == .Deleted)))
  252. {
  253. typeOptions.mCreateState = .Normal;
  254. continue;
  255. }
  256. if (apply)
  257. appliedChange = true;
  258. mDeferredDeleteList.Add(typeOptions);
  259. @typeOptions.Remove();
  260. }
  261. return appliedChange;
  262. }
  263. protected void SetupDistinctBuildOptions(PropEntry propEntry)
  264. {
  265. propEntry.mNotSetString = "<Wildcard>";
  266. UpdateDistinctBuildOptions(propEntry);
  267. propEntry.mOnUpdate.Add(new () => { UpdateDistinctBuildOptions(propEntry); return true; });
  268. propEntry.mIsTypeWildcard = true;
  269. ImageWidget closeWidget = new ImageWidget();
  270. closeWidget.mImage = DarkTheme.sDarkTheme.GetImage(.Close);
  271. closeWidget.mOverImage = DarkTheme.sDarkTheme.GetImage(.CloseOver);
  272. closeWidget.mOnMouseClick.Add(new (evt) =>
  273. {
  274. let valueItem = propEntry.mListViewItem.GetSubItem(1);
  275. if (!valueItem.Label.IsEmpty)
  276. {
  277. let dialog = ThemeFactory.mDefault.CreateDialog("Remove?", "Are you sure you want to remove the selected distinct build options?");
  278. dialog.AddYesNoButtons(new (evt) =>
  279. {
  280. DeleteDistinctBuildOptions(propEntry.mListViewItem);
  281. }, null, 0, 1);
  282. dialog.PopupWindow(mWidgetWindow);
  283. }
  284. else
  285. {
  286. DeleteDistinctBuildOptions(propEntry.mListViewItem);
  287. }
  288. });
  289. let subItem = propEntry.mListViewItem.GetSubItem(1);
  290. subItem.AddWidget(closeWidget);
  291. subItem.mOnResized.Add(new (evt) =>
  292. {
  293. let width = GetValueEditWidth(subItem);
  294. closeWidget.Resize(width - GS!(21), GS!(-1), GS!(20), subItem.mHeight + 1);
  295. });
  296. }
  297. }
  298. }