CreateAGemScreen.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <GemCatalog/GemCatalogHeaderWidget.h>
  9. #include <CreateAGemScreen.h>
  10. #include <ProjectUtils.h>
  11. #include <PythonBindingsInterface.h>
  12. #include <QMessageBox>
  13. #include <QPushButton>
  14. #include <QStackedWidget>
  15. #include <QLabel>
  16. #include <QDialogButtonBox>
  17. namespace O3DE::ProjectManager
  18. {
  19. CreateAGemScreen::CreateAGemScreen(QWidget* parent)
  20. : ScreenWidget(parent)
  21. {
  22. QVBoxLayout* vLayout = new QVBoxLayout(this);
  23. vLayout->setSpacing(0);
  24. vLayout->setContentsMargins(0, 0, 0, 0);
  25. m_tabWidget = new TabWidget(this);
  26. m_tabWidget->setContentsMargins(0, 0, 0, 0);
  27. m_tabWidget->setObjectName("createAGemTab");
  28. m_tabWidget->addTab(CreateFirstScreen(), tr("1. Gem Setup"));
  29. m_tabWidget->addTab(CreateSecondScreen(), tr("2. Gem Details"));
  30. m_tabWidget->addTab(CreateThirdScreen(), tr("3. Creator Details"));
  31. m_tabWidget->tabBar()->setEnabled(false);
  32. vLayout->addWidget(m_tabWidget);
  33. QFrame* footerFrame = new QFrame(this);
  34. footerFrame->setObjectName("createAGemFooter");
  35. m_backNextButtons = new QDialogButtonBox(this);
  36. m_backNextButtons->setObjectName("footer");
  37. QVBoxLayout* footerLayout = new QVBoxLayout();
  38. footerLayout->setContentsMargins(0, 0, 0, 0);
  39. footerFrame->setLayout(footerLayout);
  40. footerLayout->addWidget(m_backNextButtons);
  41. vLayout->addWidget(footerFrame);
  42. m_backButton = m_backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole);
  43. m_backButton->setProperty("secondary", true);
  44. m_nextButton = m_backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole);
  45. connect(m_tabWidget, &TabWidget::currentChanged, this, &CreateAGemScreen::UpdateNextButtonToCreate);
  46. connect(m_backButton, &QPushButton::clicked, this, &CreateAGemScreen::HandleBackButton);
  47. connect(m_nextButton, &QPushButton::clicked, this, &CreateAGemScreen::HandleNextButton);
  48. setObjectName("createAGemBody");
  49. setLayout(vLayout);
  50. }
  51. void CreateAGemScreen::LoadButtonsFromGemTemplatePaths([[maybe_unused]]QVBoxLayout* firstScreen)
  52. {
  53. m_radioButtonGroup = new QButtonGroup();
  54. auto templatesResult = PythonBindingsInterface::Get()->GetGemTemplates();
  55. if (templatesResult.IsSuccess() && !templatesResult.GetValue().isEmpty())
  56. {
  57. m_gemTemplates = templatesResult.GetValue();
  58. for (int index = 0; index < m_gemTemplates.size(); ++index)
  59. {
  60. ProjectTemplateInfo gemTemplate = m_gemTemplates.at(index);
  61. QRadioButton* button = new QRadioButton(gemTemplate.m_displayName);
  62. button->setObjectName("createAGem");
  63. m_radioButtonGroup->addButton(button, index);
  64. QLabel* buttonSubtext = new QLabel();
  65. buttonSubtext->setObjectName("createAGemRadioButtonSubtext");
  66. buttonSubtext->setText(gemTemplate.m_summary);
  67. if (index == 0)
  68. {
  69. button->click();
  70. }
  71. firstScreen->addWidget(button);
  72. firstScreen->addWidget(buttonSubtext);
  73. }
  74. }
  75. }
  76. QScrollArea* CreateAGemScreen::CreateFirstScreen()
  77. {
  78. QScrollArea* firstScreenScrollArea = new QScrollArea(this);
  79. firstScreenScrollArea->setWidgetResizable(true);
  80. firstScreenScrollArea->setMinimumWidth(660);
  81. firstScreenScrollArea->setObjectName("createAGemRightPane");
  82. QFrame* firstScreenFrame = new QFrame();
  83. QWidget* firstScreenScrollWidget = new QWidget();
  84. firstScreenScrollArea->setWidget(firstScreenScrollWidget);
  85. QVBoxLayout* firstScreen = new QVBoxLayout(this);
  86. firstScreen->setAlignment(Qt::AlignTop);
  87. firstScreen->addWidget(firstScreenFrame);
  88. firstScreenScrollWidget->setLayout(firstScreen);
  89. QLabel* rightPaneHeader = new QLabel();
  90. rightPaneHeader->setObjectName("rightPaneHeader");
  91. rightPaneHeader->setText(tr("Please Choose a Gem Template"));
  92. QLabel* rightPaneSubheader = new QLabel();
  93. rightPaneSubheader->setObjectName("rightPaneSubheader");
  94. rightPaneSubheader->setText(tr("Gems can contain assets such as scripts, animations, meshes, textures, and more."));
  95. firstScreen->addWidget(rightPaneHeader);
  96. firstScreen->addWidget(rightPaneSubheader);
  97. LoadButtonsFromGemTemplatePaths(firstScreen);
  98. m_formFolderRadioButton = new QRadioButton("Choose existing template");
  99. m_formFolderRadioButton->setObjectName("createAGem");
  100. m_radioButtonGroup->addButton(m_formFolderRadioButton);
  101. m_gemTemplateLocation = new FormFolderBrowseEditWidget(tr("Gem Template Location*"), "");
  102. firstScreen->addWidget(m_formFolderRadioButton);
  103. firstScreen->addWidget(m_gemTemplateLocation);
  104. return firstScreenScrollArea;
  105. }
  106. QScrollArea* CreateAGemScreen::CreateSecondScreen()
  107. {
  108. QScrollArea* secondScreenScrollArea = new QScrollArea(this);
  109. secondScreenScrollArea->setWidgetResizable(true);
  110. secondScreenScrollArea->setMinimumWidth(660);
  111. secondScreenScrollArea->setObjectName("createAGemRightPane");
  112. QFrame* secondScreenFrame = new QFrame();
  113. QWidget* secondScreenScrollWidget = new QWidget();
  114. secondScreenScrollArea->setWidget(secondScreenScrollWidget);
  115. QVBoxLayout* secondScreen = new QVBoxLayout(this);
  116. secondScreen->setAlignment(Qt::AlignTop);
  117. secondScreen->addWidget(secondScreenFrame);
  118. secondScreenScrollWidget->setLayout(secondScreen);
  119. QLabel* secondRightPaneHeader = new QLabel();
  120. secondRightPaneHeader->setObjectName("rightPaneHeader");
  121. secondRightPaneHeader->setText(tr("Enter Gem Details"));
  122. secondScreen->addWidget(secondRightPaneHeader);
  123. m_gemDisplayName = new FormLineEditWidget(tr("Gem Display name*"), "");
  124. QLineEdit* gemDisplayLineEdit = m_gemDisplayName->lineEdit();
  125. gemDisplayLineEdit->setPlaceholderText(tr("The name displayed on the Gem Catalog"));
  126. secondScreen->addWidget(m_gemDisplayName);
  127. m_gemSystemName = new FormLineEditWidget(tr("Gem System name*"), "");
  128. QLineEdit* gemSystemLineEdit = m_gemSystemName->lineEdit();
  129. gemSystemLineEdit->setPlaceholderText(tr("The name used in the O3DE Gem System"));
  130. secondScreen->addWidget(m_gemSystemName);
  131. m_gemSummary = new FormLineEditWidget(tr("Gem Summary"), "");
  132. QLineEdit* gemSummaryLineEdit = m_gemSummary->lineEdit();
  133. gemSummaryLineEdit->setPlaceholderText(tr("A short description of your Gem"));
  134. secondScreen->addWidget(m_gemSummary);
  135. m_requirements = new FormLineEditWidget(tr("Requirements"), "");
  136. QLineEdit* requirementsLineEdit = m_requirements->lineEdit();
  137. requirementsLineEdit->setPlaceholderText(tr("Notice of any requirements your Gem. i.e. This requires X other gem"));
  138. secondScreen->addWidget(m_requirements);
  139. m_license = new FormLineEditWidget(tr("License*"), "");
  140. QLineEdit* licenseLineEdit = m_license->lineEdit();
  141. licenseLineEdit->setPlaceholderText(tr("License uses goes here: i.e. Apache-2.0 or MIT"));
  142. secondScreen->addWidget(m_license);
  143. m_licenseURL = new FormLineEditWidget(tr("License URL"), "");
  144. QLineEdit* licenseURLLineEdit = m_licenseURL->lineEdit();
  145. licenseURLLineEdit->setPlaceholderText(tr("Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0"));
  146. secondScreen->addWidget(m_licenseURL);
  147. m_origin = new FormLineEditWidget(tr("Origin"), "");
  148. QLineEdit* originLineEdit = m_origin->lineEdit();
  149. originLineEdit->setPlaceholderText(tr("The name of the originator goes. i.e. XYZ Inc."));
  150. secondScreen->addWidget(m_origin);
  151. m_originURL = new FormLineEditWidget(tr("Origin URL"), "");
  152. QLineEdit* originURLLineEdit = m_originURL->lineEdit();
  153. originURLLineEdit->setPlaceholderText(tr("The primary repo for your Gem. i.e. http://www.mydomain.com"));
  154. secondScreen->addWidget(m_originURL);
  155. m_firstDropdown = new FormComboBoxWidget(tr("Global Gem Tag*"));
  156. AddDropdownActions(m_firstDropdown);
  157. secondScreen->addWidget(m_firstDropdown);
  158. m_secondDropdown = new FormComboBoxWidget(tr("Optional Global Gem Tag"));
  159. AddDropdownActions(m_secondDropdown);
  160. secondScreen->addWidget(m_secondDropdown);
  161. m_thirdDropdown = new FormComboBoxWidget(tr("Optional Global Gem Tag"));
  162. AddDropdownActions(m_thirdDropdown);
  163. secondScreen->addWidget(m_thirdDropdown);
  164. m_userDefinedGemTags = new FormLineEditWidget(tr("User-defined Gem Tags (Comma separated list)"), "");
  165. secondScreen->addWidget(m_userDefinedGemTags);
  166. m_gemLocation = new FormFolderBrowseEditWidget(tr("Gem Location"), "");
  167. QLineEdit* gemLocationLineEdit = m_gemLocation->lineEdit();
  168. const char* gemLocationPlaceholderText = R"(C:\O3DE\Project\Gems\YourGem)";
  169. gemLocationLineEdit->setPlaceholderText(tr(gemLocationPlaceholderText));
  170. secondScreen->addWidget(m_gemLocation);
  171. m_gemIconPath = new FormFolderBrowseEditWidget(tr("Gem Icon Path"), "");
  172. QLineEdit* gemIconPathLineEdit = m_gemIconPath->lineEdit();
  173. gemIconPathLineEdit->setPlaceholderText(tr("Select Gem icon path"));
  174. secondScreen->addWidget(m_gemIconPath);
  175. m_documentationURL = new FormLineEditWidget(tr("Documentation URL"), "");
  176. QLineEdit* documentationURLLineEdit = m_documentationURL->lineEdit();
  177. documentationURLLineEdit->setPlaceholderText(tr("Link to any documentation of your Gem i.e. https://o3de.org/docs/user-guide/gems/..."));
  178. secondScreen->addWidget(m_documentationURL);
  179. return secondScreenScrollArea;
  180. }
  181. QScrollArea* CreateAGemScreen::CreateThirdScreen()
  182. {
  183. QScrollArea* thirdScreenScrollArea = new QScrollArea(this);
  184. thirdScreenScrollArea->setWidgetResizable(true);
  185. thirdScreenScrollArea->setMinimumWidth(660);
  186. thirdScreenScrollArea->setObjectName("createAGemRightPane");
  187. QFrame* thirdScreenFrame = new QFrame();
  188. QWidget* thirdScreenScrollWidget = new QWidget();
  189. thirdScreenScrollArea->setWidget(thirdScreenScrollWidget);
  190. QVBoxLayout* thirdScreen = new QVBoxLayout();
  191. thirdScreen->setAlignment(Qt::AlignTop);
  192. thirdScreen->addWidget(thirdScreenFrame);
  193. thirdScreenScrollWidget->setLayout(thirdScreen);
  194. QLabel* thirdRightPaneHeader = new QLabel(this);
  195. thirdRightPaneHeader->setObjectName("rightPaneHeader");
  196. thirdRightPaneHeader->setText(tr("Enter your Details"));
  197. thirdScreen->addWidget(thirdRightPaneHeader);
  198. m_creatorName = new FormLineEditWidget(tr("Creator Name*"), "", this);
  199. QLineEdit* creatorNameLineEdit = m_creatorName->lineEdit();
  200. creatorNameLineEdit->setPlaceholderText(tr("John Smith"));
  201. thirdScreen->addWidget(m_creatorName);
  202. m_repositoryURL = new FormLineEditWidget(tr("Repository URL*"), "", this);
  203. QLineEdit* repositoryURLLineEdit = m_repositoryURL->lineEdit();
  204. repositoryURLLineEdit->setPlaceholderText(tr("https://github.com/Jane"));
  205. thirdScreen->addWidget(m_repositoryURL);
  206. return thirdScreenScrollArea;
  207. }
  208. bool CreateAGemScreen::ValidateGemTemplateLocation()
  209. {
  210. bool gemTemplateLocationFilled = true;
  211. if (m_formFolderRadioButton->isChecked())
  212. {
  213. if (m_gemTemplateLocation->lineEdit()->text().isEmpty())
  214. {
  215. gemTemplateLocationFilled = false;
  216. m_gemTemplateLocation->setErrorLabelText(tr("A path must be provided."));
  217. }
  218. }
  219. m_gemTemplateLocation->setErrorLabelVisible(!gemTemplateLocationFilled);
  220. return gemTemplateLocationFilled;
  221. }
  222. bool CreateAGemScreen::ValidateGemDisplayName()
  223. {
  224. bool gemScreenNameIsValid = true;
  225. if (m_gemDisplayName->lineEdit()->text().isEmpty())
  226. {
  227. gemScreenNameIsValid = false;
  228. m_gemDisplayName->setErrorLabelText(tr("A gem display name is required."));
  229. }
  230. m_gemDisplayName->setErrorLabelVisible(!gemScreenNameIsValid);
  231. return gemScreenNameIsValid;
  232. }
  233. bool CreateAGemScreen::ValidateGemSystemName()
  234. {
  235. bool gemSystemNameIsValid = true;
  236. if (m_gemSystemName->lineEdit()->text().isEmpty())
  237. {
  238. gemSystemNameIsValid = false;
  239. m_gemSystemName->setErrorLabelText(tr("A gem system name is required."));
  240. }
  241. else
  242. {
  243. std::string gemSystemName = m_gemSystemName->lineEdit()->text().toStdString();
  244. _int64 count = std::count_if(
  245. gemSystemName.begin(),
  246. gemSystemName.end(),
  247. [](char c)
  248. {
  249. return !(std::isalnum(c));
  250. });
  251. if (count > 0)
  252. {
  253. gemSystemNameIsValid = false;
  254. m_gemSystemName->setErrorLabelText(tr("A gem system name can only contain alphanumeric characters."));
  255. }
  256. }
  257. m_gemSystemName->setErrorLabelVisible(!gemSystemNameIsValid);
  258. return gemSystemNameIsValid;
  259. }
  260. bool CreateAGemScreen::ValidateLicenseName()
  261. {
  262. bool licenseNameIsValid = true;
  263. if (m_license->lineEdit()->text().isEmpty())
  264. {
  265. licenseNameIsValid = false;
  266. m_license->setErrorLabelText(tr("License details are required."));
  267. }
  268. m_license->setErrorLabelVisible(!licenseNameIsValid);
  269. return licenseNameIsValid;
  270. }
  271. bool CreateAGemScreen::ValidateGlobalGemTag()
  272. {
  273. bool globalGemTagIsValid = true;
  274. if (m_firstDropdown->comboBox()->currentIndex() == 0)
  275. {
  276. globalGemTagIsValid = false;
  277. m_firstDropdown->setErrorLabelText(tr("At least one global gem tag is required."));
  278. }
  279. m_firstDropdown->setErrorLabelVisible(!globalGemTagIsValid);
  280. return globalGemTagIsValid;
  281. }
  282. bool CreateAGemScreen::ValidateOptionalGemTags()
  283. {
  284. bool firstOptionalGemTagIsValid = true;
  285. bool secondOptionalGemTagIsValid = true;
  286. if (m_secondDropdown->comboBox()->currentIndex() != 0 && m_secondDropdown->comboBox()->currentIndex() ==
  287. m_firstDropdown->comboBox()->currentIndex())
  288. {
  289. firstOptionalGemTagIsValid = false;
  290. m_secondDropdown->setErrorLabelText(tr("This gem has already been selected"));
  291. }
  292. if (m_thirdDropdown->comboBox()->currentIndex() != 0 && (m_thirdDropdown->comboBox()->currentIndex() == m_secondDropdown->comboBox()->currentIndex() ||
  293. m_thirdDropdown->comboBox()->currentIndex() == m_firstDropdown->comboBox()->currentIndex()))
  294. {
  295. secondOptionalGemTagIsValid = false;
  296. m_thirdDropdown->setErrorLabelText(tr("This gem has already been selected"));
  297. }
  298. m_secondDropdown->setErrorLabelVisible(!firstOptionalGemTagIsValid);
  299. m_thirdDropdown->setErrorLabelVisible(!secondOptionalGemTagIsValid);
  300. return firstOptionalGemTagIsValid && secondOptionalGemTagIsValid;
  301. }
  302. bool CreateAGemScreen::ValidateCreatorName()
  303. {
  304. bool creatorNameIsValid = true;
  305. if (m_creatorName->lineEdit()->text().isEmpty())
  306. {
  307. creatorNameIsValid = false;
  308. m_creatorName->setErrorLabelText(tr("A creator's name is required."));
  309. }
  310. m_creatorName->setErrorLabelVisible(!creatorNameIsValid);
  311. return creatorNameIsValid;
  312. }
  313. bool CreateAGemScreen::ValidateRepositoryURL()
  314. {
  315. bool repositoryURLIsValid = true;
  316. if (m_repositoryURL->lineEdit()->text().isEmpty())
  317. {
  318. repositoryURLIsValid = false;
  319. m_repositoryURL->setErrorLabelText(tr("A repository URL is required."));
  320. }
  321. m_repositoryURL->setErrorLabelVisible(!repositoryURLIsValid);
  322. return repositoryURLIsValid;
  323. }
  324. void CreateAGemScreen::HandleBackButton()
  325. {
  326. if (m_tabWidget->currentIndex() == 2)
  327. {
  328. m_tabWidget->setCurrentIndex(1);
  329. m_nextButton->setText(tr("Next"));
  330. }
  331. else if (m_tabWidget->currentIndex() == 1)
  332. {
  333. m_backButton->setVisible(false);
  334. m_tabWidget->setCurrentIndex(0);
  335. }
  336. else if (m_tabWidget->currentIndex() == 0)
  337. {
  338. m_backButton->setVisible(false);
  339. }
  340. }
  341. void CreateAGemScreen::HandleNextButton()
  342. {
  343. if (m_tabWidget->currentIndex() == 0)
  344. {
  345. bool templateLocationIsValid = ValidateGemTemplateLocation();
  346. if (!m_formFolderRadioButton->isChecked())
  347. {
  348. m_backButton->setVisible(true);
  349. m_tabWidget->setCurrentIndex(1);
  350. }
  351. else if (templateLocationIsValid && m_formFolderRadioButton->isChecked())
  352. {
  353. m_backButton->setVisible(true);
  354. m_tabWidget->setCurrentIndex(1);
  355. }
  356. }
  357. else if (m_tabWidget->currentIndex() == 1)
  358. {
  359. bool displayNameIsValid = ValidateGemDisplayName();
  360. bool systemNameIsValid = ValidateGemSystemName();
  361. bool licenseNameIsValid = ValidateLicenseName();
  362. bool globalGemTagIsValid = ValidateGlobalGemTag();
  363. bool optionalGemTagsAreValid = ValidateOptionalGemTags();
  364. if (systemNameIsValid && licenseNameIsValid && globalGemTagIsValid && displayNameIsValid && optionalGemTagsAreValid)
  365. {
  366. m_createAGemInfo.m_displayName = m_gemDisplayName->lineEdit()->text();
  367. m_createAGemInfo.m_name = m_gemSystemName->lineEdit()->text();
  368. m_createAGemInfo.m_summary = m_gemSummary->lineEdit()->text();
  369. m_createAGemInfo.m_requirement = m_requirements->lineEdit()->text();
  370. m_createAGemInfo.m_licenseText = m_license->lineEdit()->text();
  371. m_createAGemInfo.m_licenseLink = m_licenseURL->lineEdit()->text();
  372. m_createAGemInfo.m_licenseText = m_license->lineEdit()->text();
  373. m_createAGemInfo.m_documentationLink = m_documentationURL->lineEdit()->text();
  374. m_createAGemInfo.m_path = m_gemLocation->lineEdit()->text();
  375. m_tabWidget->setCurrentIndex(2);
  376. m_nextButton->setText(tr("Create"));
  377. }
  378. }
  379. else if (m_tabWidget->currentIndex() == 2)
  380. {
  381. bool creatorNameIsValid = ValidateCreatorName();
  382. bool repoURLIsValid = ValidateRepositoryURL();
  383. if (creatorNameIsValid && repoURLIsValid)
  384. {
  385. m_createAGemInfo.m_creator = m_creatorName->lineEdit()->text();
  386. m_createAGemInfo.m_repoUri = m_repositoryURL->lineEdit()->text();
  387. auto result = PythonBindingsInterface::Get()->CreateGem(m_gemTemplateLocation->lineEdit()->text(), m_createAGemInfo);
  388. emit CreateButtonPressed();
  389. }
  390. }
  391. }
  392. void CreateAGemScreen::UpdateNextButtonToCreate()
  393. {
  394. if (m_tabWidget->currentIndex() == 2)
  395. {
  396. m_nextButton->setText(tr("Create"));
  397. }
  398. else
  399. {
  400. m_nextButton->setText(tr("Next"));
  401. }
  402. }
  403. void CreateAGemScreen::AddDropdownActions(FormComboBoxWidget* dropdown)
  404. {
  405. QComboBox* comboBox = dropdown->comboBox();
  406. comboBox->addItem(tr(""));
  407. comboBox->addItem(tr("Achievements"));
  408. comboBox->addItem(tr("Animation"));
  409. comboBox->addItem(tr("Assets"));
  410. comboBox->addItem(tr("Audio"));
  411. comboBox->addItem(tr("Barrier"));
  412. comboBox->addItem(tr("Content"));
  413. comboBox->addItem(tr("Core"));
  414. comboBox->addItem(tr("Creation"));
  415. comboBox->addItem(tr("DCC"));
  416. comboBox->addItem(tr("Debug"));
  417. comboBox->addItem(tr("Design"));
  418. comboBox->addItem(tr("Digital"));
  419. comboBox->addItem(tr("Editor"));
  420. comboBox->addItem(tr("Environment"));
  421. comboBox->addItem(tr("Framework"));
  422. comboBox->addItem(tr("Gameplay"));
  423. comboBox->addItem(tr("Input"));
  424. comboBox->addItem(tr("Materials"));
  425. comboBox->addItem(tr("Multiplayer"));
  426. comboBox->addItem(tr("Network"));
  427. comboBox->addItem(tr("PBR"));
  428. comboBox->addItem(tr("Physics"));
  429. comboBox->addItem(tr("Profiler"));
  430. comboBox->addItem(tr("Rendering"));
  431. comboBox->addItem(tr("SDK"));
  432. comboBox->addItem(tr("Sample"));
  433. comboBox->addItem(tr("Scripting"));
  434. comboBox->addItem(tr("Simulation"));
  435. comboBox->addItem(tr("Slices"));
  436. comboBox->addItem(tr("Synergy"));
  437. comboBox->addItem(tr("Terrain"));
  438. comboBox->addItem(tr("Tools"));
  439. comboBox->addItem(tr("UI"));
  440. comboBox->addItem(tr("Unity"));
  441. }
  442. } // namespace O3DE::ProjectManager