7 #include <unordered_set>
92 using std::make_unique;
96 using std::string_view;
97 using std::unique_ptr;
98 using std::unordered_set;
181 EditorScreenController::EditorScreenController(
EditorView* view): fileEntitiesMutex(
"fileentities-mutex")
199 screenNode = GUIParser::parse(
"resources/engine/gui",
"screen_editor.xml");
219 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectlibrary_import"))->getController()->setDisabled(
true);
220 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpathfiles_search"))->getController()->setDisabled(
true);
221 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpaths_search"))->getController()->setDisabled(
true);
222 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_projectlibrary_add"))->getController()->setDisabled(
true);
223 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_outliner_add"))->getController()->setDisabled(
true);
224 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"outliner_search"))->getController()->setDisabled(
true);
231 Console::println(
"EditorScreenController::initialize(): An error occurred: " +
string(exception.what()));
234 class EditorLogger:
public Console::Logger {
236 EditorLogger(
EditorScreenController* editorScreenController): editorScreenController(editorScreenController) {
238 void println(
const string_view& str) {
239 auto& messages = editorScreenController->
logMessages;
240 if (messages.empty() ==
true || newline ==
true) messages.push_back(
string());
241 messages[messages.size() - 1]+= str;
242 if (messages.size() == Console::HISTORY_LINECOUNT) messages.erase(messages.begin());
246 void print(
const string_view& str) {
247 auto& messages = editorScreenController->
logMessages;
248 if (messages.empty() ==
true || newline ==
true) messages.push_back(
string());
249 messages[messages.size() - 1]+= str;
250 if (messages.size() == Console::HISTORY_LINECOUNT) messages.erase(messages.begin());
255 auto& messages = editorScreenController->
logMessages;
256 messages.push_back(
string());
257 if (messages.size() == Console::HISTORY_LINECOUNT) messages.erase(messages.begin());
263 bool newline {
false };
266 Console::setLogger(
new EditorLogger(
this));
293 if (node->
getId() ==
"projectpathfiles_search") {
297 if (node->
getId() ==
"selectbox_projectpaths") {
303 if (node->
getId() ==
"dropdown_projectlibrary_add") {
308 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onChange(node);
314 if (node->
getId() ==
"menu_file_open") {
317 if (node->
getId() ==
"menu_file_save") {
319 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_SAVE);
321 if (node->
getId() ==
"menu_file_saveas") {
323 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_SAVEAS);
325 if (node->
getId() ==
"menu_file_saveall") {
328 tab->getTabView()->getTabController()->onCommand(TabController::COMMAND_SAVE);
331 if (node->
getId() ==
"menu_edit_undo") {
333 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_UNDO);
335 if (node->
getId() ==
"menu_edit_redo") {
337 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_REDO);
339 if (node->
getId() ==
"menu_edit_cut") {
341 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_CUT);
343 if (node->
getId() ==
"menu_edit_copy") {
345 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_COPY);
347 if (node->
getId() ==
"menu_edit_paste") {
349 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_PASTE);
351 if (node->
getId() ==
"menu_edit_delete") {
353 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_DELETE);
355 if (node->
getId() ==
"menu_edit_selectall") {
357 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_SELECTALL);
359 if (node->
getId() ==
"menu_edit_findreplace") {
361 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onCommand(TabController::COMMAND_FINDREPLACE);
363 if (node->
getId() ==
"menu_view_fullscreen") {
366 if (node->
getId() ==
"menu_help_guixml_documentation") {
367 openFile(FileSystem::getInstance()->getCurrentWorkingPathName() +
"/README-GUI-XML.md");
369 if (node->
getId() ==
"menu_help_miniscript_documentation") {
370 openFile(FileSystem::getInstance()->getCurrentWorkingPathName() +
"/README-MiniScript.md");
372 if (node->
getId() ==
"menu_help_about") {
375 if (StringTools::startsWith(node->
getId(),
"projectpathfiles_file_") ==
true) {
376 onOpenFile(required_dynamic_cast<GUIElementNode*>(node)->getValue());
378 if (StringTools::startsWith(node->
getId(),
"menu_view_tab_") ==
true) {
379 selectTabAt(Integer::parse(StringTools::substring(node->
getId(),
string(
"menu_view_tab_").size())));
381 if (StringTools::startsWith(node->
getId(),
"tab_") ==
true) {
384 if (StringTools::startsWith(node->
getId(), tab->getId() +
"_close") ==
true) {
385 tabIdToClose = tab->getId();
388 if (tabIdToClose.empty() ==
false)
closeTab(tabIdToClose);
390 if (node->
getId() ==
"menu_file_quit") {
396 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onAction(type, node);
402 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onFocus(node);
408 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onUnfocus(node);
412 if (StringTools::startsWith(node->
getId(),
"projectpathfiles_file_") ==
true) {
414 auto absoluteFileName = required_dynamic_cast<GUIElementNode*>(node)->getValue();
418 path = FileSystem::getInstance()->isPath(absoluteFileName);
426 class OnOpenAction:
public virtual Action
429 OnOpenAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
431 void performAction()
override {
432 editorScreenController->
openFile(absoluteFileName);
436 string absoluteFileName;
445 class OnCopyPathAction:
public virtual Action
448 OnCopyPathAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
450 void performAction()
override {
451 Application::getApplication()->setClipboardContent(absoluteFileName);
455 string absoluteFileName;
462 class OnDuplicateAction:
public virtual Action
465 OnDuplicateAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
467 void performAction()
override {
468 class DuplicateFileAction:
public virtual Action
471 DuplicateFileAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
474 void performAction()
override {
479 if (FileSystem::getInstance()->isPath(absoluteFileName) ==
false) {
480 extension = Tools::getFileExtension(absoluteFileName);
483 vector<uint8_t> fileContent;
484 FileSystem::getInstance()->getContent(
485 Tools::getPathName(absoluteFileName),
486 Tools::getFileName(absoluteFileName),
490 FileSystem::getInstance()->setContent(
491 Tools::getPathName(absoluteFileName),
492 (extension.empty() ==
true?
494 Tools::ensureFileExtension(duplicateFileName, extension)
499 editorScreenController->
reload();
501 editorScreenController->
showInfoPopUp(
"Warning", exception.what());
507 string absoluteFileName;
512 Tools::removeFileExtension(Tools::getFileName(absoluteFileName)),
513 new DuplicateFileAction(editorScreenController, absoluteFileName)
518 string absoluteFileName;
525 class OnRenameAction:
public virtual Action
528 OnRenameAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
530 void performAction()
override {
531 class RenameFileAction:
public virtual Action
534 RenameFileAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
537 void performAction()
override {
542 if (FileSystem::getInstance()->isPath(absoluteFileName) ==
false) {
543 extension = Tools::getFileExtension(absoluteFileName);
546 FileSystem::getInstance()->rename(
548 Tools::getPathName(absoluteFileName) +
"/" +
549 (extension.empty() ==
true?
551 Tools::ensureFileExtension(renameFileName, extension)
555 editorScreenController->
reload();
557 editorScreenController->
showInfoPopUp(
"Warning", exception.what());
563 string absoluteFileName;
568 Tools::removeFileExtension(Tools::getFileName(absoluteFileName)),
569 new RenameFileAction(editorScreenController, absoluteFileName)
574 string absoluteFileName;
581 class OnMoveAction:
public virtual Action
584 OnMoveAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
586 void performAction()
override {
587 class FileMoveAction:
public virtual Action
594 FileMoveAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
597 void performAction()
override {
601 FileSystem::getInstance()->rename(
603 moveToPath +
"/" + Tools::getFileName(absoluteFileName)
606 editorScreenController->
reload();
608 editorScreenController->
showInfoPopUp(
"Warning", exception.what());
615 string absoluteFileName;
625 new FileMoveAction(editorScreenController, absoluteFileName)
630 string absoluteFileName;
636 class OnDeleteAction:
public virtual Action
639 OnDeleteAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
641 void performAction()
override {
643 if (FileSystem::getInstance()->isPath(absoluteFileName) ==
true) {
644 FileSystem::getInstance()->removePath(absoluteFileName,
true);
646 FileSystem::getInstance()->removeFile(Tools::getPathName(absoluteFileName), Tools::getFileName(absoluteFileName));
649 editorScreenController->
reload();
651 Console::println(
"OnDeleteAction::performAction(): An error occurred: " +
string(exception.what()));
656 string absoluteFileName;
664 if (selectedTab !=
nullptr) {
665 switch (selectedTab->getType()) {
670 class OnAddToSceneAction:
public virtual Action
673 OnAddToSceneAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
675 void performAction()
override {
677 if (currentTab ==
nullptr)
return;
679 if (sceneEditorTabView ==
nullptr)
return;
682 auto prototype = PrototypeReader::read(
683 Tools::getPathName(absoluteFileName),
684 Tools::getFileName(absoluteFileName)
687 prototype->setEmbedded(
false);
691 Console::println(
"OnOpenAction::performAction(): An error occurred: " +
string(exception.what()));
692 editorScreenController->
showInfoPopUp(
"Warning", exception.what());
697 string absoluteFileName;
714 class OnShowInFileBrowserAction:
public virtual Action
717 OnShowInFileBrowserAction(
EditorScreenController* editorScreenController,
const string& absoluteFileName): editorScreenController(editorScreenController), absoluteFileName(absoluteFileName) {
719 void performAction()
override {
721 if (FileSystem::getInstance()->isPath(absoluteFileName) ==
true) {
722 Application::openBrowser(absoluteFileName);
724 Application::openBrowser(Tools::getPathName(absoluteFileName));
727 Console::println(
"OnShowInFileBrowserAction::performAction(): An error occurred: " +
string(exception.what()));
732 string absoluteFileName;
741 if (selectedTab !=
nullptr) selectedTab->getTabView()->getTabController()->onContextMenuRequest(node, mouseX, mouseY);
755 if (StringTools::startsWith(node->
getId(),
"projectpathfiles_file_") ==
true) {
757 class OnDragReleaseAction:
public Action {
761 OnDragReleaseAction(
EditorScreenController* editorScreenController): editorScreenController(editorScreenController) {}
762 virtual void performAction() {
765 if (selectedTab ==
nullptr) {
766 editorScreenController->
showInfoPopUp(
"Warning",
"No tab opened to drop files into");
768 selectedTab->getTabView()->getTabController()->onDrop(
769 draggingScreenController->getPayload(),
770 draggingScreenController->getDragReleaseMouseX(),
771 draggingScreenController->getDragReleaseMouseY()
777 auto absoluteFileName = node->
getValue();
779 auto xml =
"<image width=\"auto\" height=\"auto\" src=\"" + imageSource +
"\" />";
786 if (StringTools::endsWith(
projectPath,
"/") ==
true) {
795 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectlibrary_import"))->getController()->setDisabled(
false);
796 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpathfiles_search"))->getController()->setDisabled(
false);
797 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpaths_search"))->getController()->setDisabled(
false);
798 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_projectlibrary_add"))->getController()->setDisabled(
false);
799 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_outliner_add"))->getController()->setDisabled(
false);
800 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"outliner_search"))->getController()->setDisabled(
false);
802 Engine::getInstance()->loadTextures(pathName);
804 GUIParser::loadProjectThemeProperties(
projectPath);
808 class OnOpenProject:
public virtual Action
815 OnOpenProject(
EditorScreenController* editorScreenController): editorScreenController(editorScreenController) {
818 void performAction()
override {
829 "Open project from folder: ",
833 new OnOpenProject(
this),
835 ".projects.filedialog.properties",
842 xml+=
"<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape(
"resources") +
"\" value=\"" + GUIParser::escape(
"resources") +
"\">\n";
844 xml+=
"</selectbox-parent-option>\n";
845 xml+=
"<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape(
"shader") +
"\" value=\"" + GUIParser::escape(
"shader") +
"\">\n";
847 xml+=
"</selectbox-parent-option>\n";
848 xml+=
"<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape(
"src") +
"\" value=\"" + GUIParser::escape(
"src") +
"\">\n";
850 xml+=
"</selectbox-parent-option>\n";
854 Console::print(
"EditorScreenController::scanProjectPaths(): An error occurred: " +
string(exception.what()));
861 virtual ~ListFilter() {}
863 bool accept(
const string& pathName,
const string& fileName)
override {
864 if (fileName ==
".")
return false;
865 if (fileName ==
"..")
return false;
866 if (FileSystem::getInstance()->isPath(pathName +
"/" + fileName) ==
true)
return true;
872 ListFilter listFilter;
873 vector<string> files;
875 if (FileSystem::getInstance()->exists(path) ==
false) {
876 Console::println(
"EditorScreenController::scanProject(): Error: file does not exist: " + path);
878 if (FileSystem::getInstance()->isPath(path) ==
false) {
879 if (listFilter.accept(
".", path) ==
true) {
880 Console::println(
"EditorScreenController::scanProject(): Error: path is file" + path);
882 Console::println(
"EditorScreenController::scanProject(): Error: file exist, but does not match filter: " + path);
885 FileSystem::getInstance()->list(path, files, &listFilter);
886 for (
const auto& fileName: files) {
887 auto relativePath = path +
"/" + fileName;
888 if (StringTools::startsWith(relativePath,
projectPath)) relativePath = StringTools::substring(relativePath,
projectPath.size() + 1, relativePath.size());
889 if (FileSystem::getInstance()->isPath(path +
"/" + fileName) ==
false) {
894 if (innerXml.empty() ==
false) {
895 xml+=
"<selectbox-parent-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape(fileName) +
"\" value=\"" + GUIParser::escape(relativePath) +
"\">\n";
897 xml+=
"</selectbox-parent-option>\n";
899 xml+=
"<selectbox-option image=\"resources/engine/images/folder.png\" text=\"" + GUIParser::escape(fileName) +
"\" value=\"" + GUIParser::escape(relativePath) +
"\" />\n";
911 auto& tab = tabIt->second;
912 tab.getTabView()->dispose();
916 if (tab->getId() == tabId)
break;
931 for (
auto& [tabId, tab]:
tabViews) {
934 tab.getTabView()->dispose();
952 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectlibrary_import"))->getController()->setDisabled(
true);
953 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpathfiles_search"))->getController()->setDisabled(
true);
954 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"projectpaths_search"))->getController()->setDisabled(
true);
955 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_projectlibrary_add"))->getController()->setDisabled(
true);
956 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"dropdown_outliner_add"))->getController()->setDisabled(
true);
957 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"outliner_search"))->getController()->setDisabled(
true);
969 Console::println(
"EditorScreenController::startScanFiles(): An error occurred: " +
string(exception.what()));
976 string scrollToNodeId;
978 xml+=
"<layout alignment=\"horizontal\">\n";
980 xml+= pendingFileEntity->buttonXML;
981 if (pendingFileEntity->scrollTo ==
true) scrollToNodeId = pendingFileEntity->id;
987 if (scrollToNodeId.empty() ==
false) {
992 Console::println(
"EditorScreenController::addPendingFileEntities(): An error occurred: " +
string(exception.what()));
996 if (pendingFileEntity->thumbnailTexture ==
nullptr)
continue;
999 required_dynamic_cast<GUIImageNode*>(
screenNode->
getNodeById(pendingFileEntity->id +
"_texture_normal"))->setTexture(pendingFileEntity->thumbnailTexture);
1000 required_dynamic_cast<GUIImageNode*>(
screenNode->
getNodeById(pendingFileEntity->id +
"_texture_mouseover"))->setTexture(pendingFileEntity->thumbnailTexture);
1001 required_dynamic_cast<GUIImageNode*>(
screenNode->
getNodeById(pendingFileEntity->id +
"_texture_clicked"))->setTexture(pendingFileEntity->thumbnailTexture);
1003 Console::println(
"EditorScreenController::addPendingFileEntities(): An error occurred: " +
string(exception.what()));
1005 if (pendingFileEntity->thumbnailTexture !=
nullptr) pendingFileEntity->thumbnailTexture->releaseReference();
1021 if (fileEntity->thumbnailTexture !=
nullptr) fileEntity->thumbnailTexture->releaseReference();
1047 auto newRelativeProjectPath = Tools::getPathName(fileName);
1048 if (StringTools::startsWith(newRelativeProjectPath,
projectPath) ==
true) newRelativeProjectPath = StringTools::substring(newRelativeProjectPath,
projectPath.size() + 1);
1058 virtual ~ListFilter() {}
1060 bool accept(
const string&
pathName,
const string& fileName)
override {
1061 if (fileName ==
".")
return false;
1062 if (fileName ==
"..")
return false;
1064 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
1066 if (
searchTerm.empty() ==
false && fileNameLowerCase.find(
searchTerm) == string::npos)
return false;
1069 if (FileSystem::getInstance()->isPath(
pathName +
"/" + fileName) ==
true)
return true;
1071 if (StringTools::endsWith(fileNameLowerCase,
".ogg") ==
true)
return true;
1073 if (StringTools::endsWith(fileNameLowerCase,
".md") ==
true)
return true;
1075 if (fileNameLowerCase ==
"license")
return true;
1077 if (StringTools::endsWith(fileNameLowerCase,
".h") ==
true)
return true;
1078 if (StringTools::endsWith(fileNameLowerCase,
".cpp") ==
true)
return true;
1079 if (StringTools::endsWith(fileNameLowerCase,
".c") ==
true)
return true;
1080 if (StringTools::endsWith(fileNameLowerCase,
".tscript") ==
true)
return true;
1082 if (StringTools::endsWith(fileNameLowerCase,
".ttf") ==
true)
return true;
1084 if (StringTools::endsWith(fileNameLowerCase,
".icns") ==
true)
return true;
1085 if (StringTools::endsWith(fileNameLowerCase,
".ico") ==
true)
return true;
1086 if (StringTools::endsWith(fileNameLowerCase,
".png") ==
true)
return true;
1088 if (StringTools::endsWith(fileNameLowerCase,
".mpg") ==
true)
return true;
1090 if (StringTools::endsWith(fileNameLowerCase,
".dae") ==
true)
return true;
1091 if (StringTools::endsWith(fileNameLowerCase,
".fbx") ==
true)
return true;
1092 if (StringTools::endsWith(fileNameLowerCase,
".glb") ==
true)
return true;
1093 if (StringTools::endsWith(fileNameLowerCase,
".gltf") ==
true)
return true;
1094 if (StringTools::endsWith(fileNameLowerCase,
".tm") ==
true)
return true;
1096 if (StringTools::endsWith(fileNameLowerCase,
".properties") ==
true)
return true;
1098 if (StringTools::endsWith(fileNameLowerCase,
".cl") ==
true)
return true;
1099 if (StringTools::endsWith(fileNameLowerCase,
".frag") ==
true)
return true;
1100 if (StringTools::endsWith(fileNameLowerCase,
".glsl") ==
true)
return true;
1101 if (StringTools::endsWith(fileNameLowerCase,
".vert") ==
true)
return true;
1103 if (StringTools::endsWith(fileNameLowerCase,
".tempty") ==
true)
return true;
1105 if (StringTools::endsWith(fileNameLowerCase,
".ttrigger") ==
true)
return true;
1107 if (StringTools::endsWith(fileNameLowerCase,
".tenvmap") ==
true)
return true;
1109 if (StringTools::endsWith(fileNameLowerCase,
".tdecal") ==
true)
return true;
1111 if (StringTools::endsWith(fileNameLowerCase,
".tmodel") ==
true)
return true;
1113 if (StringTools::endsWith(fileNameLowerCase,
".tscene") ==
true)
return true;
1115 if (StringTools::endsWith(fileNameLowerCase,
".tparticle") ==
true)
return true;
1117 if (StringTools::endsWith(fileNameLowerCase,
".tterrain") ==
true)
return true;
1119 if (StringTools::endsWith(fileNameLowerCase,
".xml") ==
true)
return true;
1121 if (StringTools::endsWith(fileNameLowerCase,
".nmake") ==
true)
return true;
1122 if (StringTools::endsWith(fileNameLowerCase,
".nmake.main") ==
true)
return true;
1124 if (StringTools::endsWith(fileNameLowerCase,
".bat") ==
true)
return true;
1126 if (StringTools::endsWith(fileNameLowerCase,
".sh") ==
true)
return true;
1127 if (StringTools::endsWith(fileNameLowerCase,
".bash") ==
true)
return true;
1129 if (fileName.rfind(
".") == string::npos ||
1130 (fileName.rfind(
"/") != string::npos &&
1131 fileName.rfind(
".") < fileName.rfind(
"/"))) {
1142 vector<string> files;
1144 if (FileSystem::getInstance()->exists(
pathName) ==
false) {
1145 Console::println(
"EditorScreenController::ScanFilesThread::run(): Error: file does not exist: " +
pathName);
1147 if (FileSystem::getInstance()->isPath(
pathName) ==
false) {
1148 if (listFilter.accept(
".",
pathName) ==
true) {
1149 Console::println(
"EditorScreenController::ScanFilesThread::run(): Error: path is file: " +
pathName);
1151 Console::println(
"EditorScreenController::ScanFilesThread::run(): Error: file exist, but does not match filter: " +
pathName);
1154 FileSystem::getInstance()->list(
pathName, files, &listFilter);
1156 auto parentPathName = FileSystem::getInstance()->getPathName(
pathName);
1158 string fileName =
"..";
1161 string templateSource =
"button_template_thumbnail_nobackground.xml";
1163 string iconBig =
"{$icon.type_folder_big}";
1166 auto fileEntity = make_unique<FileEntity>();
1167 fileEntity->id =
"projectpathfiles_file_" + GUIParser::escape(StringTools::replace(Tools::getFileName(fileName),
'.',
'_'));
1168 fileEntity->buttonXML =
1171 "id=\"" + fileEntity->id +
"\" " +
1172 "value=\"" + GUIParser::escape(parentPathName) +
"\" " +
1173 "template=\"" + templateSource +
"\" " +
1175 "icon=\"" + GUIParser::escape(icon) +
"\" " +
1176 "icon-big=\"" + GUIParser::escape(iconBig) +
"\" " +
1177 "filename=\"" + GUIParser::escape(fileName) +
"\" " +
1183 for (
const auto& fileName: files) {
1187 auto absolutePath =
pathName +
"/" + fileName;
1188 if (FileSystem::getInstance()->isPath(
pathName +
"/" + fileName) ==
false)
continue;
1190 string templateSource =
"button_template_thumbnail_nobackground.xml";
1192 string iconBig =
"{$icon.type_folder_big}";
1195 auto fileEntity = make_unique<FileEntity>();
1196 fileEntity->id =
"projectpathfiles_file_" + GUIParser::escape(StringTools::replace(Tools::getFileName(fileName),
'.',
'_'));
1199 string buttonOnInitialize;
1201 fileEntity->scrollTo =
true;
1202 buttonOnInitialize =
"on-initialize=\"" + fileEntity->id +
".condition+=selected\" ";
1205 fileEntity->buttonXML =
1208 "id=\"" + fileEntity->id +
"\" " +
1209 "value=\"" + GUIParser::escape(absolutePath) +
"\" " +
1210 "template=\"" + templateSource +
"\" " +
1212 "icon=\"" + GUIParser::escape(icon) +
"\" " +
1213 "icon-big=\"" + GUIParser::escape(iconBig) +
"\" " +
1214 "filename=\"" + GUIParser::escape(fileName) +
"\" " +
1215 buttonOnInitialize +
1221 for (
const auto& fileName: files) {
1224 auto absolutePath =
pathName +
"/" + fileName;
1225 if (FileSystem::getInstance()->isPath(
pathName +
"/" + fileName) ==
true)
continue;
1231 string icon =
"{$icon.type_" + image +
"}";
1232 string iconBig =
"{$icon.type_" + image +
"_big}";
1233 string typeColor =
"{$color.type_" + image +
"}";
1236 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
1239 string templateSource =
"button_template_thumbnail.xml";
1240 Texture* thumbnailTexture =
nullptr;
1241 vector<uint8_t> thumbnailPNGData;
1242 if (StringTools::endsWith(fileNameLowerCase,
".png") ==
true) {
1243 thumbnailTexture = TextureReader::read(
pathName, fileName,
false);
1245 if ((((StringTools::endsWith(fileNameLowerCase,
".tmodel") ==
true || StringTools::endsWith(fileNameLowerCase,
".tdecal") ==
true) && PrototypeReader::readThumbnail(
pathName, fileName, thumbnailPNGData) ==
true) ||
1246 (StringTools::endsWith(fileNameLowerCase,
".tm") ==
true && FileSystem::getInstance()->getThumbnailAttachment(
pathName, fileName, thumbnailPNGData) ==
true)) &&
1247 thumbnailPNGData.empty() ==
false) {
1248 static int thumbnailIdx = 0;
1249 thumbnailTexture = PNGTextureReader::read(
"tdme.editor.projectpathfiles." + to_string(thumbnailIdx++), thumbnailPNGData,
false);
1251 if (thumbnailTexture !=
nullptr) {
1255 if (textureWidth > textureHeight) {
1256 scale = 128.0f /
static_cast<float>(textureWidth);
1258 scale = 128.0f /
static_cast<float>(textureHeight);
1260 auto scaledTextureWidth =
static_cast<int>(
static_cast<float>(textureWidth) * scale);
1261 auto scaledTextureHeight =
static_cast<int>(
static_cast<float>(textureHeight) * scale);
1262 if (textureWidth != scaledTextureWidth || textureHeight != scaledTextureHeight) {
1263 auto thumbnailTextureScaled = TextureReader::scale(thumbnailTexture, scaledTextureWidth, scaledTextureHeight);
1265 thumbnailTexture = thumbnailTextureScaled;
1269 if (iconBig.empty() ==
false) icon.clear();
1272 auto fileEntity = make_unique<FileEntity>();
1273 fileEntity->id =
"projectpathfiles_file_" + GUIParser::escape(StringTools::replace(Tools::getFileName(fileName),
'.',
'_'));
1276 string buttonOnInitialize;
1278 fileEntity->scrollTo =
true;
1279 buttonOnInitialize =
"on-initialize=\"" + fileEntity->id +
".condition+=selected\" ";
1282 fileEntity->buttonXML =
1285 "id=\"" + fileEntity->id +
"\" " +
1286 "value=\"" + GUIParser::escape(absolutePath) +
"\" " +
1287 "template=\"" + templateSource +
"\" " +
1289 "icon=\"" + GUIParser::escape(icon) +
"\" " +
1290 "icon-big=\"" + GUIParser::escape(iconBig) +
"\" " +
1291 "filename=\"" + GUIParser::escape(fileName) +
"\" " +
1292 "type-color=\"" + GUIParser::escape(typeColor) +
"\" " +
1293 buttonOnInitialize +
1296 fileEntity->thumbnailTexture = thumbnailTexture;
1304 Console::println(
"EditorScreenController::ScanFilesThread::run(): Error: " +
errorMessage);
1312 class OnAddFile:
public virtual Action
1315 OnAddFile(
EditorScreenController* editorScreenController,
const string& type,
const string& extension): editorScreenController(editorScreenController), type(type), extension(extension) {
1318 void performAction()
override {
1319 editorScreenController->
addFile(
1321 (extension.empty() ==
true?
1336 if (type !=
"folder") {
1337 if (type ==
"logic_script") extension =
"tscript";
else
1338 if (type ==
"gui_script") extension =
"tscript";
else
1339 if (type ==
"screen" || type ==
"template") extension =
"xml";
else
1340 extension =
"t" + type;
1345 string(
"Add ") + type +
" to project: ",
1347 new OnAddFile(
this, type, extension)
1352 if (type ==
"folder") {
1354 FileSystem::getInstance()->createPath(pathName +
"/" + fileName);
1355 browseTo(pathName +
"/" + fileName);
1357 showInfoPopUp(
"Error",
string() +
"An error occurred: file type: " + type +
": " + exception.what());
1360 if (type ==
"screen") {
1362 FileSystem::getInstance()->setContentFromString(
1365 StringTools::replace(
1366 FileSystem::getInstance()->getContentAsString(
"resources/engine/templates/gui",
"screen.xml"),
1368 Tools::removeFileExtension(fileName)
1371 browseTo(pathName +
"/" + fileName);
1372 openFile(pathName +
"/" + fileName);
1374 showInfoPopUp(
"Error",
string() +
"An error occurred: file type: " + type +
": " + exception.what());
1377 if (type ==
"template") {
1379 FileSystem::getInstance()->setContentFromString(pathName, fileName, FileSystem::getInstance()->getContentAsString(
"resources/engine/templates/gui",
"template.xml"));
1380 browseTo(pathName +
"/" + fileName);
1381 openFile(pathName +
"/" + fileName);
1383 showInfoPopUp(
"Error",
string() +
"An error occurred: file type: " + type +
": " + exception.what());
1386 if (type ==
"logic_script") {
1388 FileSystem::getInstance()->setContentFromString(pathName, fileName, FileSystem::getInstance()->getContentAsString(
"resources/engine/templates/tscript",
"logic_script_template.tscript"));
1389 browseTo(pathName +
"/" + fileName);
1390 openFile(pathName +
"/" + fileName);
1392 showInfoPopUp(
"Error",
string() +
"An error occurred: file type: " + type +
": " + exception.what());
1395 if (type ==
"gui_script") {
1397 FileSystem::getInstance()->setContentFromString(pathName, fileName, FileSystem::getInstance()->getContentAsString(
"resources/engine/templates/tscript",
"gui_script_template.tscript"));
1398 browseTo(pathName +
"/" + fileName);
1399 openFile(pathName +
"/" + fileName);
1401 showInfoPopUp(
"Error",
string() +
"An error occurred: file type: " + type +
": " + exception.what());
1404 unique_ptr<Prototype> prototype;
1405 unique_ptr<Scene> scene;
1406 if (type ==
"empty") {
1407 prototype = make_unique<Prototype>(
1409 Prototype_Type::EMPTY,
1410 Tools::removeFileExtension(fileName),
1411 Tools::removeFileExtension(fileName),
1412 pathName +
"/" + fileName,
1413 "resources/engine/models/empty.tm",
1415 ModelReader::read(
"resources/engine/models",
"empty.tm")
1418 if (type ==
"trigger") {
1422 auto boundingBox =
BoundingBox(
Vector3(-width / 2.0f, 0.0f, -depth / 2.0f),
Vector3(+width / 2.0f, height, +depth / 2.0f));
1423 prototype = make_unique<Prototype>(
1425 Prototype_Type::TRIGGER,
1426 Tools::removeFileExtension(fileName),
1427 Tools::removeFileExtension(fileName),
1428 pathName +
"/" + fileName,
1434 prototype->getBoundingVolume(0)->setupAabb(boundingBox.getMin(), boundingBox.getMax());
1436 if (type ==
"envmap") {
1440 auto boundingBox =
BoundingBox(
Vector3(-width / 2.0f, 0.0f, -depth / 2.0f),
Vector3(+width / 2.0f, height, +depth / 2.0f));
1441 prototype = make_unique<Prototype>(
1443 Prototype_Type::ENVIRONMENTMAPPING,
1444 Tools::removeFileExtension(fileName),
1445 Tools::removeFileExtension(fileName),
1446 pathName +
"/" + fileName,
1452 prototype->getBoundingVolume(0)->setupAabb(boundingBox.getMin(), boundingBox.getMax());
1454 if (type ==
"decal") {
1458 auto boundingBox =
BoundingBox(
Vector3(-width / 2.0f, 0.0f, -depth / 2.0f),
Vector3(+width / 2.0f, height, +depth / 2.0f));
1459 prototype = make_unique<Prototype>(
1461 Prototype_Type::DECAL,
1462 Tools::removeFileExtension(fileName),
1463 Tools::removeFileExtension(fileName),
1464 pathName +
"/" + fileName,
1470 prototype->getBoundingVolume(0)->setupAabb(boundingBox.getMin(), boundingBox.getMax());
1472 if (type ==
"model") {
1473 prototype = make_unique<Prototype>(
1475 Prototype_Type::MODEL,
1476 Tools::removeFileExtension(fileName),
1477 Tools::removeFileExtension(fileName),
1478 pathName +
"/" + fileName,
1479 "resources/engine/models/empty.tm",
1481 ModelReader::read(
"resources/engine/models",
"empty.tm")
1484 if (type ==
"terrain") {
1485 prototype = make_unique<Prototype>(
1487 Prototype_Type::TERRAIN,
1488 Tools::removeFileExtension(fileName),
1489 Tools::removeFileExtension(fileName),
1490 pathName +
"/" + fileName,
1496 if (type ==
"particle") {
1497 prototype = make_unique<Prototype>(
1499 Prototype_Type::PARTICLESYSTEM,
1500 Tools::removeFileExtension(fileName),
1501 Tools::removeFileExtension(fileName),
1502 pathName +
"/" + fileName,
1508 if (type ==
"scene") {
1509 scene = make_unique<Scene>(
1510 Tools::removeFileExtension(fileName),
1511 Tools::removeFileExtension(fileName)
1514 if (prototype !=
nullptr) {
1516 PrototypeWriter::write(pathName, fileName, prototype.get());
1517 browseTo(pathName +
"/" + fileName);
1518 openFile(pathName +
"/" + fileName);
1520 Console::println(
"EditorScreenController::addFile(): An error occurred: " +
string(exception.what()));
1521 showInfoPopUp(
"Error",
string() +
"An error occurred: " + exception.what());
1524 if (scene !=
nullptr) {
1526 SceneWriter::write(pathName, fileName, scene.get());
1527 browseTo(pathName +
"/" + fileName);
1528 openFile(pathName +
"/" + fileName);
1530 Console::println(
"EditorScreenController::addFile(): An error occurred: " +
string(exception.what()));
1531 showInfoPopUp(
"Error",
string() +
"An error occurred: " + exception.what());
1534 showInfoPopUp(
"Error",
string() +
"Unknown file type: " + type);
1540 auto fileName = FileSystem::getInstance()->getFileName(absoluteFileName);
1547 auto model = ModelReader::read(Tools::getPathName(absoluteFileName), Tools::getFileName(absoluteFileName));
1548 prototype = make_unique<Prototype>(
1550 Prototype_Type::MODEL,
1551 Tools::removeFileExtension(fileName),
1552 Tools::removeFileExtension(fileName),
1553 FileSystem::getInstance()->getPathName(absoluteFileName) +
"/" + Tools::removeFileExtension(fileName) +
".tmodel",
1562 prototype = unique_ptr<Prototype>(
1563 PrototypeReader::read(
1564 FileSystem::getInstance()->getPathName(absoluteFileName),
1565 FileSystem::getInstance()->getFileName(absoluteFileName)
1572 prototype = unique_ptr<Prototype>(
1573 PrototypeReader::read(
1574 FileSystem::getInstance()->getPathName(absoluteFileName),
1575 FileSystem::getInstance()->getFileName(absoluteFileName)
1582 scene = unique_ptr<Scene>(
1584 "resources/engine/scenes/envmap",
1588 prototype = unique_ptr<Prototype>(
1589 PrototypeReader::read(
1590 FileSystem::getInstance()->getPathName(absoluteFileName),
1591 FileSystem::getInstance()->getFileName(absoluteFileName)
1598 prototype = unique_ptr<Prototype>(
1599 PrototypeReader::read(
1600 FileSystem::getInstance()->getPathName(absoluteFileName),
1601 FileSystem::getInstance()->getFileName(absoluteFileName)
1608 prototype = unique_ptr<Prototype>(
1609 PrototypeReader::read(
1610 FileSystem::getInstance()->getPathName(absoluteFileName),
1611 FileSystem::getInstance()->getFileName(absoluteFileName)
1618 prototype = unique_ptr<Prototype>(
1619 PrototypeReader::read(
1620 FileSystem::getInstance()->getPathName(absoluteFileName),
1621 FileSystem::getInstance()->getFileName(absoluteFileName)
1628 prototype = unique_ptr<Prototype>(
1629 PrototypeReader::read(
1630 FileSystem::getInstance()->getPathName(absoluteFileName),
1631 FileSystem::getInstance()->getFileName(absoluteFileName)
1638 scene = unique_ptr<Scene>(
1640 FileSystem::getInstance()->getPathName(absoluteFileName),
1641 FileSystem::getInstance()->getFileName(absoluteFileName)
1648 throw ExceptionBase(
"File type not supported by EditorScreenController::FileOpenThread");
1652 throw ExceptionBase(
"File type not supported by EditorScreenController::FileOpenThread");
1656 throw ExceptionBase(
"File type not supported by EditorScreenController::FileOpenThread");
1660 throw ExceptionBase(
"File type not supported by EditorScreenController::FileOpenThread");
1664 throw ExceptionBase(
"File type not supported by EditorScreenController::FileOpenThread");
1670 errorMessage = string(exception.what());
1671 Console::println(
"EditorScreenController::FileOpenThread::run(): An error occurred: " + errorMessage);
1683 if (selectedTabId == tab->getId())
return idx;
1699 auto tab =
getTab(tabId);
1710 Console::println(
"EditorScreenController::openFile(): " + absoluteFileName +
": file open thread is already busy with opening a file");
1711 showInfoPopUp(
"Error",
string() +
"File open thread is already busy with opening a file");
1716 if (FileSystem::getInstance()->isPath(absoluteFileName)) {
1725 auto tabId =
"tab_" + StringTools::replace(absoluteFileName,
".",
"_");
1727 tabId = GUIParser::escape(tabId);
1730 auto fileName = FileSystem::getInstance()->getFileName(absoluteFileName);
1731 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
1733 if (StringTools::endsWith(fileNameLowerCase,
".xml") ==
true) {
1736 if (StringTools::endsWith(fileNameLowerCase,
".tempty") ==
true) {
1739 if (StringTools::endsWith(fileNameLowerCase,
".ttrigger") ==
true) {
1742 if (StringTools::endsWith(fileNameLowerCase,
".tenvmap") ==
true) {
1745 if (StringTools::endsWith(fileNameLowerCase,
".tdecal") ==
true) {
1748 if (StringTools::endsWith(fileNameLowerCase,
".tscene") ==
true) {
1751 if (StringTools::endsWith(fileNameLowerCase,
".tmodel") ==
true) {
1754 if (StringTools::endsWith(fileNameLowerCase,
".tparticle") ==
true) {
1757 if (StringTools::endsWith(fileNameLowerCase,
".tterrain") ==
true) {
1760 if (StringTools::endsWith(fileNameLowerCase,
".ttf") ==
true) {
1763 if (StringTools::endsWith(fileNameLowerCase,
".ogg") ==
true) {
1766 if (StringTools::endsWith(fileNameLowerCase,
".mpg") ==
true) {
1769 if (StringTools::endsWith(fileNameLowerCase,
".md") ==
true) {
1772 if (fileNameLowerCase ==
"license" ||
1773 StringTools::endsWith(fileNameLowerCase,
".h") ==
true ||
1774 StringTools::endsWith(fileNameLowerCase,
".cpp") ==
true ||
1775 StringTools::endsWith(fileNameLowerCase,
".c") ==
true ||
1776 StringTools::endsWith(fileNameLowerCase,
".tscript") ==
true ||
1777 StringTools::endsWith(fileNameLowerCase,
".properties") ==
true ||
1778 StringTools::endsWith(fileNameLowerCase,
".cl") ==
true ||
1779 StringTools::endsWith(fileNameLowerCase,
".frag") ==
true ||
1780 StringTools::endsWith(fileNameLowerCase,
".glsl") ==
true ||
1781 StringTools::endsWith(fileNameLowerCase,
".vert") ==
true ||
1782 StringTools::endsWith(fileNameLowerCase,
".xml") ==
true ||
1783 StringTools::endsWith(fileNameLowerCase,
".nmake") ==
true ||
1784 StringTools::endsWith(fileNameLowerCase,
".nmake.main") ==
true ||
1785 StringTools::endsWith(fileNameLowerCase,
".bat") ==
true ||
1786 StringTools::endsWith(fileNameLowerCase,
".sh") ==
true ||
1787 StringTools::endsWith(fileNameLowerCase,
".bash") ==
true ||
1788 (fileName.rfind(
".") == string::npos || (fileName.rfind(
"/") != string::npos && fileName.rfind(
".") < fileName.rfind(
"/")))) {
1791 for (
const auto& extension: ModelReader::getModelExtensions()) {
1792 if (StringTools::endsWith(fileNameLowerCase,
"." + extension) ==
true) {
1797 for (
const auto& extension: TextureReader::getTextureExtensions()) {
1798 if (StringTools::endsWith(fileNameLowerCase,
"." + extension) ==
true) {
1815 string viewPortTemplate;
1820 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1827 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1834 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1841 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1848 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1855 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1862 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1869 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1876 fileOpenThread = make_unique<FileOpenThread>(tabId, fileType, absoluteFileName);
1919 Console::println(
"EditorScreenController::openFile(): An error occurred: " +
string(exception.what()));
1922 showInfoPopUp(
"Error",
"An error occurred: " +
string(exception.what()));
1927 auto fileName = FileSystem::getInstance()->getFileName(absoluteFileName);
1928 auto fileNameLowerCase = StringTools::toLowerCase(fileName);
1935 unique_ptr<TabView> tabView;
1936 string viewPortTemplate;
1940 icon =
"{$icon.type_mesh}";
1941 colorType =
"{$color.type_mesh}";
1943 tabView = make_unique<ModelEditorTabView>(
view, tabId, prototype.release());
1944 viewPortTemplate =
"template_viewport_scene.xml";
1949 icon =
"{$icon.type_prototype}";
1950 colorType =
"{$color.type_prototype}";
1952 tabView = make_unique<EmptyEditorTabView>(
view, tabId, prototype.release());
1953 viewPortTemplate =
"template_viewport_scene.xml";
1958 icon =
"{$icon.type_prototype}";
1959 colorType =
"{$color.type_prototype}";
1961 tabView = make_unique<TriggerEditorTabView>(
view, tabId, prototype.release());
1962 viewPortTemplate =
"template_viewport_scene.xml";
1967 icon =
"{$icon.type_scene}";
1968 colorType =
"{$color.type_scene}";
1970 tabView = make_unique<EnvMapEditorTabView>(
view, tabId, scene.release(), prototype.release());
1971 viewPortTemplate =
"template_viewport_scene.xml";
1976 icon =
"{$icon.type_decal}";
1977 colorType =
"{$color.type_prototype}";
1979 tabView = make_unique<DecalEditorTabView>(
view, tabId, prototype.release());
1980 viewPortTemplate =
"template_viewport_scene.xml";
1985 icon =
"{$icon.type_prototype}";
1986 colorType =
"{$color.type_prototype}";
1988 tabView = make_unique<ModelEditorTabView>(
view, tabId, prototype.release());
1989 viewPortTemplate =
"template_viewport_scene.xml";
1994 icon =
"{$icon.type_terrain}";
1995 colorType =
"{$color.type_terrain}";
1997 tabView = make_unique<TerrainEditorTabView>(
view, tabId, prototype.release());
1998 viewPortTemplate =
"template_viewport_terrain.xml";
2003 icon =
"{$icon.type_particle}";
2004 colorType =
"{$color.type_particle}";
2006 tabView = make_unique<ParticleSystemEditorTabView>(
view, tabId, prototype.release());
2007 viewPortTemplate =
"template_viewport_scene.xml";
2012 icon =
"{$icon.type_scene}";
2013 colorType =
"{$color.type_scene}";
2015 tabView = make_unique<SceneEditorTabView>(
view, tabId, scene.release());
2016 viewPortTemplate =
"template_viewport_scene.xml";
2024 xmlRootNode = GUIParser::getRootNode(
2025 FileSystem::getInstance()->getPathName(absoluteFileName),
2026 FileSystem::getInstance()->getFileName(absoluteFileName)
2029 Console::println(
"EditorScreenController::openFile(): " + absoluteFileName +
": " +
string(exception.what()));
2032 if (xmlRootNode ==
"screen" || xmlRootNode ==
"template") {
2033 icon =
"{$icon.type_gui}";
2034 colorType =
"{$color.type_gui}";
2036 tabView = make_unique<UIEditorTabView>(
view, tabId,
screenNode, absoluteFileName);
2037 viewPortTemplate =
"template_viewport_ui.xml";
2040 icon =
"{$icon.type_script}";
2041 colorType =
"{$color.type_script}";
2043 FileSystem::getInstance()->getContentAsString(
2044 FileSystem::getInstance()->getPathName(absoluteFileName),
2045 FileSystem::getInstance()->getFileName(absoluteFileName)
2049 "resources/engine/gui/",
2051 {{
"text", StringTools::replace(StringTools::replace(text,
"[",
"\\["),
"]",
"\\]") }}
2055 tabView = make_unique<TextEditorTabView>(
view, tabId,
screenNode.release(), absoluteFileName);
2056 viewPortTemplate =
"template_viewport_plain.xml";
2062 icon =
"{$icon.type_sound}";
2063 colorType =
"{$color.type_sound}";
2064 auto audioStream = make_unique<VorbisAudioStream>(
2066 FileSystem::getInstance()->getPathName(absoluteFileName),
2067 FileSystem::getInstance()->getFileName(absoluteFileName)
2071 "resources/engine/gui/",
2076 tabView = make_unique<SoundTabView>(
view, tabId,
screenNode.release(), audioStream.release());
2077 viewPortTemplate =
"template_viewport_plain.xml";
2082 icon =
"{$icon.type_texture}";
2083 colorType =
"{$color.type_texture}";
2086 "resources/engine/gui/",
2088 {{
"texture", absoluteFileName}}
2092 tabView = make_unique<TextureTabView>(
view, tabId,
screenNode.release());
2093 viewPortTemplate =
"template_viewport_plain.xml";
2098 icon =
"{$icon.type_texture}";
2099 colorType =
"{$color.type_texture}";
2102 "resources/engine/gui/",
2104 {{
"video", absoluteFileName}}
2108 tabView = make_unique<VideoTabView>(
view, tabId,
screenNode.release());
2109 viewPortTemplate =
"template_viewport_plain.xml";
2114 icon =
"{$icon.type_font}";
2115 colorType =
"{$color.type_font}";
2118 "resources/engine/gui/",
2121 {
"font", absoluteFileName },
2127 tabView = make_unique<FontTabView>(
view, tabId,
screenNode.release());
2128 viewPortTemplate =
"template_viewport_plain.xml";
2133 auto hasVisualCode = StringTools::endsWith(fileNameLowerCase,
".tscript");
2134 icon =
"{$icon.type_script}";
2135 colorType =
"{$color.type_script}";
2137 FileSystem::getInstance()->getContentAsString(
2138 FileSystem::getInstance()->getPathName(absoluteFileName),
2139 FileSystem::getInstance()->getFileName(absoluteFileName)
2143 "resources/engine/gui/",
2144 hasVisualCode ==
true?
"tab_visualcode.xml":
"tab_text.xml",
2145 {{
"text", StringTools::replace(StringTools::replace(text,
"[",
"\\["),
"]",
"\\]") }}
2149 tabView = make_unique<TextEditorTabView>(
view, tabId,
screenNode.release(), absoluteFileName);
2150 viewPortTemplate = hasVisualCode ==
true?
"template_viewport_visualcode.xml":
"template_viewport_plain.xml";
2155 icon =
"{$icon.type_script}";
2156 colorType =
"{$color.type_script}";
2157 vector<Markdown::TOCEntry> toc;
2160 Markdown::createGUIXML(
2161 FileSystem::getInstance()->getPathName(absoluteFileName),
2162 FileSystem::getInstance()->getFileName(absoluteFileName),
2168 tabView = make_unique<MarkdownTabView>(
view, tabId,
screenNode.release(), toc);
2169 viewPortTemplate =
"template_viewport_plain.xml";
2177 string tabsHeaderXML =
"<tab id=\"" + tabId +
"\" image=\"" + GUIParser::escape(icon) +
"\" type-color=\"" + GUIParser::escape(colorType) +
"\" value=\"" + GUIParser::escape(absoluteFileName) +
"\" text=\"" + GUIParser::escape(fileName) +
"\" closeable=\"true\" />\n";
2181 Console::println(
"EditorScreenController::onOpenFile(): An error occurred: " +
string(exception.what()));
2185 string tabsContentXML =
2186 "<tab-content tab-id=\"" + tabId +
"\">\n" +
2187 " <template id=\"" + tabId +
"_tab\" src=\"resources/engine/gui/" + viewPortTemplate +
"\" />\n" +
2192 Console::println(
"EditorScreenController::onOpenFile(): An error occurred: " +
string(exception.what()));
2196 tabView->initialize();
2199 if (Engine::getInstance()->getGraphicsRendererType() != Renderer::RENDERERTYPE_VULKAN) {
2207 Console::println(
"EditorScreenController::onOpenFileFinish(): An error occurred: " +
string(exception.what()));
2210 showInfoPopUp(
"Error",
"An error occurred: " +
string(exception.what()));
2222 required_dynamic_cast<GUISelectBoxController*>(
outliner->
getController())->determineExpandedParentOptionValues(outlinerState.expandedOutlinerParentOptionValues);
2223 outlinerState.value = required_dynamic_cast<GUISelectBoxController*>(
outliner->
getController())->getValue();
2229 required_dynamic_cast<GUISelectBoxController*>(
outliner->
getController())->expandParentOptionsByValues(outlinerState.expandedOutlinerParentOptionValues);
2230 required_dynamic_cast<GUISelectBoxController*>(
outliner->
getController())->setValue(outlinerState.value);
2248 Console::println(
"EditorScreenController::setOutlinerContent(): An error occurred: " +
string(exception.what()));
2257 Console::println(
"EditorScreenController::setOutlinerAddDropDownContent(): An error occurred: " +
string(exception.what()));
2265 Console::println(
"EditorScreenController::setDetailsContent(): An error occurred: " +
string(exception.what()));
2270 return required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"screen_editor_screen"))->getActiveConditions().has(
"fullscreen");
2274 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"menu_view_fullscreen"))->getController()->setDisabled(
tabViews.empty() ==
true);
2282 string xml =
"<menu-separator />\n";
2285 xml+=
"<menu-item image='" + imageSource +
"' text='" + GUIParser::escape(tab->getName()) +
"' id='menu_view_tab_" + to_string(tabIdx) +
"' shortcut='Ctrl+" + to_string(tabIdx + 1) +
"' />\n";
2289 required_dynamic_cast<GUIParentNode*>(
screenNode->
getNodeById(
"menu_view_tabs"))->addSubNodes(xml,
true);
2291 Console::println(
"EditorScreenController::updateTabsMenuEntries(): An error occurred: " +
string(exception.what()));
2296 if (fullScreen ==
true) {
2298 if (selectedTab !=
nullptr) {
2299 Application::getApplication()->setFullScreen(
true);
2304 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"screen_editor_screen"))->getActiveConditions().add(
"fullscreen");
2309 selectedTabNode->getPadding().
left = 0;
2310 selectedTabNode->getPadding().top = 0;
2311 selectedTabNode->getPadding().right = 0;
2312 selectedTabNode->getPadding().bottom = 0;
2316 Application::getApplication()->setFullScreen(
false);
2324 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"screen_editor_screen"))->getActiveConditions().remove(
"fullscreen");
2329 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"menu_view_scene_run"))->getController()->setDisabled(
false);
2330 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"menu_view_scene_stop"))->getController()->setDisabled(
false);
2334 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"menu_view_scene_run"))->getController()->setDisabled(
true);
2335 required_dynamic_cast<GUIElementNode*>(
screenNode->
getNodeById(
"menu_view_scene_stop"))->getController()->setDisabled(
true);
2340 const auto& padding = viewPortNode->
getPadding();
2341 left = constraints.
left + constraints.alignmentLeft + constraints.contentAlignmentLeft;
2342 top = constraints.top + constraints.alignmentTop + constraints.contentAlignmentTop;
2343 width = constraints.width - (padding.left + padding.right);
2344 height = constraints.height - (padding.top + padding.bottom);
2352 auto now = Time::getCurrentMillis();
2369 showInfoPopUp(
"Error",
string() +
"An error occurred: Unknown error");
2385 showInfoPopUp(
"Error",
string() +
"An error occurred: Unknown error");
2409 log.
append(StringTools::replace(StringTools::replace(logMessage,
"[",
"\\["),
"]",
"\\]"));
2415 if (logScrollareaController->isAtBottom() ==
true) logScrollareaController->scrollToBottom();
2421 if (node ==
nullptr)
return false;
2423 while (_node !=
nullptr) {
2424 if (_node->isConditionsMet() ==
false || _node->isLayouted() ==
false) {
2430 auto gui = Engine::getInstance()->getGUI();
Application base class, please make sure to allocate application on heap to have correct application ...
uint16_t getTextureHeight() const
uint16_t getTextureWidth() const
PNG texture reader class.
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Prototype bounding volume definition.
Interface to lighting shader program.
Shadow mapping shader to create a shadow map.
Shadow mapping shader to render shadow maps.
GUI select box controller.
const string & getValue()
GUI node controller base class.
virtual void setValue(const MutableString &value)=0
Set value.
virtual const MutableString & getValue()=0
const string & getToolTip()
GUIParentNode * getParentNode()
GUINodeController * getController()
GUINode_Padding & getPadding()
bool isCoordinateBelongingToNode(const Vector2 &coordinate, Vector2 &nodeCoordinate)
Is coordinate belonging to node.
GUINode_ComputedConstraints & getComputedConstraints()
GUI parent node base class thats supporting child nodes.
GUI screen node that represents a screen that can be rendered via GUI system.
void addContextMenuRequestListener(GUIContextMenuRequestListener *listener)
Add context menu request listener.
void addDragRequestListener(GUIDragRequestListener *listener)
Add drag request listener.
void addChangeListener(GUIChangeListener *listener)
Add change listener.
void addTooltipRequestListener(GUITooltipRequestListener *listener)
Add tooltip request listener.
void removeNodeById(const string &nodeId, bool resetScrollOffsets)
Remove GUI node by id.
void addActionListener(GUIActionListener *listener)
Add action listener.
void addFocusListener(GUIFocusListener *listener)
Add focus listener.
GUINode * getInnerNodeById(const string &nodeId)
Get inner GUI node by id.
GUINode * getNodeById(const string &nodeId)
Get GUI node by id.
void setText(const MutableString &text)
Set text.
void setTextureMatrix(const Matrix3x3 &textureMatrix)
Set texture matrix.
Matrix3x3 class representing matrix3x3 mathematical structure and operations for 2d space.
Matrix3x3 & identity()
Creates identity matrix.
Matrix3x3 & scale(float scalar)
Scales by scalar.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
File system singleton class.
bool isStopRequested()
Returns if stop has been requested.
Particle system editor tab view.
Mutable utf8 aware string class.
MutableString & append(char c)
Append character.
const string & getString() const
Properties class, which helps out with storeing or loading key value pairs from/to property files.
virtual void releaseReference()
Releases a reference, thus decrementing the counter and delete it if reference counter is zero.
std::exception Exception
Exception base class.
File system file name filter interface.