void TileSet::LoadResources(gd::Project &game) { try { gd::ImageResource & image = dynamic_cast<gd::ImageResource&>(game.GetResourcesManager().GetResource(textureName)); //Load the resource into a wxBitmap (IDE only) and also get its SFMLTextureWrapper #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) //Force to change the working directory to make it work wxString oldWorkingDir = wxGetCwd(); wxSetWorkingDirectory(wxFileName::FileName(game.GetProjectFile()).GetPath()); #endif m_tilesetTexture = game.GetImageManager()->GetSFMLTexture(textureName); #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) wxSetWorkingDirectory(oldWorkingDir); if ( wxFileExists(image.GetAbsoluteFile(game)) ) { m_tilesetBitmap.LoadFile(image.GetAbsoluteFile(game), wxBITMAP_TYPE_ANY); } #endif //Readjust the m_collidable std::vector according to the number of tiles m_collidable.resize(GetTilesCount(), true); } catch(...) { m_tilesetTexture = std::shared_ptr<SFMLTextureWrapper>(); } }
gd::BaseEvent::EditEventReturnType CppCodeEvent::EditEvent( wxWindow* parent_, gd::Project& game_, gd::Layout& scene_, gd::MainFrameWrapper& mainFrameWrapper_) { #if !defined(GD_NO_WX_GUI) EditCppCodeEvent dialog(parent_, *this, game_, scene_); int returned = dialog.ShowModal(); if (returned == 0) return Cancelled; else { // Force recreation of the assocaited source file wxFileName outputFile(associatedGDManagedSourceFile); outputFile.MakeAbsolute( wxFileName::FileName(game_.GetProjectFile()).GetPath()); if (wxFileExists(outputFile.GetFullPath())) wxRemoveFile(outputFile.GetFullPath()); EnsureAssociatedSourceFileIsUpToDate(game_); if (returned == 2) return ChangesMadeButNoNeedForEventsRecompilation; else return ChangesMade; } #else return ChangesMade; #endif }
void TileSet::LoadResources(gd::Project &game) { m_dirty = true; if(game.GetResourcesManager().HasResource(textureName)) { gd::ImageResource & image = dynamic_cast<gd::ImageResource&>(game.GetResourcesManager().GetResource(textureName)); //Load the resource into a wxBitmap (IDE only) and also get its SFMLTextureWrapper #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) //Force to change the working directory to make it work wxString oldWorkingDir = wxGetCwd(); wxSetWorkingDirectory(wxFileName::FileName(game.GetProjectFile()).GetPath()); #endif m_tilesetTexture = game.GetImageManager()->GetSFMLTexture(textureName); #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) wxSetWorkingDirectory(oldWorkingDir); if ( wxFileExists(image.GetAbsoluteFile(game)) ) { wxBitmap bmp( image.GetAbsoluteFile(game), wxBITMAP_TYPE_ANY); m_tilesetBitmap = bmp; } #endif } else { m_tilesetTexture = std::shared_ptr<SFMLTextureWrapper>(); } }
bool MainFrame::Save(gd::Project & project, wxString file) { bool isJSON = file.EndsWith(".json"); bool success = (!isJSON && gd::ProjectFileWriter::SaveToFile(project, file)) || (isJSON && gd::ProjectFileWriter::SaveToJSONFile(project, file)); SetLastUsedFile(project.GetProjectFile()); return success; }
void GD_API CodeCompilationHelpers::CreateExternalSourceFileCompilationTask(gd::Project & game, SourceFile & file, gd::Layout * scene) { CodeCompilerTask task; wxFileName inputFile(file.GetFileName()); inputFile.MakeAbsolute(wxFileName::FileName(game.GetProjectFile()).GetPath()); task.compilerCall.inputFile = ToString(inputFile.GetFullPath()); task.compilerCall.outputFile = string(CodeCompiler::Get()->GetOutputDirectory()+"GD"+ToString(&file)+"ObjectFile.o"); task.compilerCall.compilationForRuntime = false; task.compilerCall.optimize = false; task.compilerCall.eventsGeneratedCode = false; task.compilerCall.extraHeaderDirectories.push_back(ToString(wxFileName::FileName(game.GetProjectFile()).GetPath())); task.scene = scene; if ( scene ) task.postWork = std::shared_ptr<CodeCompilerExtraWork>(new SourceFileCodeCompilerPostWork(scene)); task.userFriendlyName = "Compilation of file "+file.GetFileName(); CodeCompiler::Get()->AddTask(task); }
gd::String Resource::GetAbsoluteFile(const gd::Project & project) const { #if !defined(GD_NO_WX_GUI) wxString projectDir = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileName filename = wxFileName::FileName(GetFile()); filename.MakeAbsolute(projectDir); return filename.GetFullPath(); #else gd::LogWarning("BAD USE: Resource::GetAbsoluteFile called when compiled with no support for wxWidgets"); return GetFile(); #endif }
bool TileMapImporter::ImportTileMap(TileSet &tileSet, TileMap &tileMap, bool importTileMap, bool importTileSetConf, bool importTileSetImage, bool importHitboxes, gd::Project &project) { //Checks the map type if(m_map->GetOrientation() != Tmx::TMX_MO_ORTHOGONAL) { gd::LogError(_("Only orthogonal maps are supported !")); return false; } //Get the tileset list if(m_map->GetNumTilesets() < 1) { gd::LogError(_("There are no tilesets in this file !")); return false; } else if(m_map->GetNumTilesets() > 1) { gd::LogWarning(_("Only the first tileset will be taken into account. Tiles from supplementary tilesets may be lost.")); } //Import the tileset image if needed if(importTileSetImage) { const Tmx::Image *importedImage = m_map->GetTileset(0)->GetImage(); wxFileName imageFileName(importedImage->GetSource()); imageFileName.MakeAbsolute(wxFileName(m_filePath).GetPath()); if(!imageFileName.FileExists()) { gd::LogError(_("The image can't be found !")); return false; } gd::String newResourceName = gd::NewNameGenerator::Generate( u8"imported_" + imageFileName.GetFullName(), [&project](const gd::String &name) -> bool { return project.GetResourcesManager().HasResource(name); } ); gd::LogMessage(_("The image is imported as ") + "\"" + newResourceName + "\"."); imageFileName.MakeRelativeTo(wxFileName(project.GetProjectFile()).GetPath()); project.GetResourcesManager().AddResource(newResourceName, imageFileName.GetFullPath(), "image"); tileSet.textureName = newResourceName; //Reload the texture tileSet.LoadResources(project); gd::LogStatus(_("Tileset image importation completed.")); } //Import the tileset configuration if wanted if(importTileSetConf) { const Tmx::Tileset *importedTileset = m_map->GetTileset(0); if(importedTileset->GetImage()->GetWidth() != tileSet.GetWxBitmap().GetWidth() || importedTileset->GetImage()->GetHeight() != tileSet.GetWxBitmap().GetHeight()) { gd::LogWarning(_("Tileset image size is not the same. Some tiles may not be rendered correctly.")); } tileSet.tileSize.x = importedTileset->GetTileWidth(); tileSet.tileSize.y = importedTileset->GetTileHeight(); tileSet.tileSpacing.x = tileSet.tileSpacing.y = importedTileset->GetSpacing(); if(importedTileset->GetMargin() > 0) { gd::LogWarning(_("Tilemap objects don't handle tilesets with margins around the images. Consider cutting the picture.")); } gd::LogStatus(_("Tileset configuration importation completed.")); } //Import the tilemap tiles if wanted if(importTileMap) { //Tilemap size if(tileMap.GetColumnsCount() != m_map->GetWidth() || tileMap.GetRowsCount() != m_map->GetHeight()) gd::LogMessage(_("Tilemap size is different.")); tileMap.SetSize(0, 0); tileMap.SetSize(m_map->GetWidth(), m_map->GetHeight()); if(!importTileSetConf && !importTileSetImage) CheckTilesCount(tileSet); //Import layers and tiles if(m_map->GetNumTileLayers() > 3) { gd::LogWarning(_("There are more than 3 tiles layers. Only the 3 firsts will be imported.")); } else if(m_map->GetNumTileLayers() < 3) { gd::LogMessage(_("There are less than 3 tiles layers. Upper layer(s) will be empty.")); } for(std::size_t i = 0; i < std::min(3, m_map->GetNumTileLayers()); i++) { const Tmx::TileLayer *layer = m_map->GetTileLayer(i); for(std::size_t x = 0; x < tileMap.GetColumnsCount(); x++) { for(std::size_t y = 0; y < tileMap.GetRowsCount(); y++) { //Only tiles provided by the first tileset are imported (and also tests for empty tiles) if(m_map->FindTilesetIndex(layer->GetTileGid(x, y)) == 0) { tileMap.SetTile(i, x, y, layer->GetTileId(x, y)); } } } } gd::LogStatus(_("Tilemap content importation completed.")); } //Import the hitboxes if(importHitboxes) { const Tmx::Tileset *importedTileset = m_map->GetTileset(0); //Set all tiles not collidable in the tileset tileSet.ResetHitboxes(); for(std::size_t i = 0; i < tileSet.GetTilesCount(); i++) tileSet.SetTileCollidable(i, false); if(!importTileSetConf && !importTileSetImage) CheckTilesCount(tileSet); bool hasMoreThanOneObjectPerTile = false; bool hasNotPolygoneObject = false; bool hasNotConvexPolygon = false; for(auto it = importedTileset->GetTiles().cbegin(); it != importedTileset->GetTiles().cend(); ++it) { const Tmx::Tile *importedTile = *it; if(importedTile->GetId() < tileSet.GetTilesCount()) //Check if the tileset has enough tiles to receive the imported hitboxes { if(importedTile->HasObjects()) { //Set the tile collidable and gets its hitbox tileSet.SetTileCollidable(importedTile->GetId(), true); TileHitbox &tileHitbox = tileSet.GetTileHitboxRef(importedTile->GetId()); //Warn the user if more than one hitbox per tile is found if(importedTile->GetNumObjects() > 1) hasMoreThanOneObjectPerTile = true; const Tmx::Object *importedObj = importedTile->GetObject(0); if(!importedObj->GetPolyline() && !importedObj->GetEllipse()) { Polygon2d polygonHitbox; if(!importedObj->GetPolygon()) { //This is a rectangle polygonHitbox = Polygon2d::CreateRectangle(importedObj->GetWidth(), importedObj->GetHeight()); polygonHitbox.Move( importedObj->GetWidth() / 2.f, importedObj->GetHeight() / 2.f ); } else { //This is a polygon const Tmx::Polygon *importedPolygon = importedObj->GetPolygon(); for(int i = 0; i < importedPolygon->GetNumPoints(); i++) { polygonHitbox.vertices.emplace_back( importedPolygon->GetPoint(i).x, importedPolygon->GetPoint(i).y ); } } polygonHitbox.Move(importedObj->GetX(), importedObj->GetY()); polygonHitbox.Rotate(importedObj->GetRot()); if(polygonHitbox.IsConvex()) tileHitbox.hitbox = polygonHitbox; else hasNotConvexPolygon = true; } else { //This is not a supported shape hasNotPolygoneObject = true; } } } } if(hasMoreThanOneObjectPerTile) gd::LogWarning(_("Some tiles have more than 1 hitbox. Only the first one is imported.")); if(hasNotPolygoneObject) gd::LogWarning(_("Some tiles have a polyline or a ellipsis hitbox. Only rectangle and polygon hitboxes are supported.")); if(hasNotConvexPolygon) gd::LogWarning(_("Some tiles have a concave polygon. It has been ignored and set to a rectangular hitbox as this object only supports convex hitboxes for tiles.")); gd::LogStatus(_("Tiles hitboxes importation completed.")); } return true; }
void ParameterEditorLauncher::LaunchEditor(wxWindow * parent, gd::Project & project, gd::Layout & layout, const gd::ParameterMetadata & metadata, std::vector<wxTextCtrl * > & paramEdits, std::size_t paramIndex) { if (paramIndex >= paramEdits.size()) return; wxTextCtrl * editCtrl = paramEdits.at(paramIndex); if (!editCtrl) return; if ( gd::ParameterMetadata::IsObject(metadata.GetType()) ) { gd::ChooseObjectDialog dialog(parent, project, layout, true, metadata.GetExtraInfo()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetChosenObject()); } return; } else if ( metadata.GetType() == "behavior" ) { gd::String object = paramEdits.empty() ? "" : paramEdits[0]->GetValue(); gd::ChooseBehaviorDialog dialog(parent, project, layout, object, metadata.GetExtraInfo()); if (dialog.DeduceBehavior() || dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetChosenBehavior()); return; } else if ( metadata.GetType() == "expression" ) { gd::EditExpressionDialog dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetExpression()); } return; } else if ( metadata.GetType() == "mouse" ) { ChoixBouton dialog(parent, editCtrl->GetValue()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.bouton); } return; } else if ( metadata.GetType() == "key" ) { ChoixClavier dialog(parent, editCtrl->GetValue()); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.selectedKey); } return; } else if ( metadata.GetType() == "string" ) { gd::EditStrExpressionDialog dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) { editCtrl->ChangeValue(dialog.GetExpression()); } return; } else if ( metadata.GetType() == "relationalOperator" ) { SigneTest dialog(parent); int chosenOperator = dialog.ShowModal(); if ( chosenOperator == 1 ) editCtrl->ChangeValue("="); if ( chosenOperator == 2 ) editCtrl->ChangeValue(">"); if ( chosenOperator == 3 ) editCtrl->ChangeValue("<"); if ( chosenOperator == 4 ) editCtrl->ChangeValue(">="); if ( chosenOperator == 5 ) editCtrl->ChangeValue("<="); if ( chosenOperator == 6 ) editCtrl->ChangeValue("!="); return; } else if ( metadata.GetType() == "color" ) { wxColour color = wxGetColourFromUser(parent, wxColour(0,0,0)); if ( color.IsOk() ) { wxString r; r << static_cast<int>(color.Red()); wxString v; v << static_cast<int>(color.Green()); wxString b; b << static_cast<int>(color.Blue()); wxString colorStr = "\""+r+";"+v+";"+b+"\""; editCtrl->ChangeValue(colorStr); } return; } else if ( metadata.GetType() == "police" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a font ( ttf/ttc files )"), projectDirectory, "", "Polices (*.ttf, *.ttc)|*.ttf;*.ttc"); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "musicfile" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a music ( ogg files )"), projectDirectory, "", _("Audio files (*.ogg)|*.ogg")); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "soundfile" ) { wxString projectDirectory = wxFileName::FileName(project.GetProjectFile()).GetPath(); wxFileDialog dialog(parent, _("Choose a sound"), projectDirectory, "", _("Audio files (*.wav, *.ogg)|*.wav;*.ogg")); dialog.ShowModal(); if ( dialog.GetPath() != "" ) //Note that path is relative to the project file: { wxFileName filename(dialog.GetPath()); filename.MakeRelativeTo(projectDirectory); editCtrl->ChangeValue(filename.GetFullPath()); } return; } else if ( metadata.GetType() == "operator" ) { SigneModification dialog(parent); int retour = dialog.ShowModal(); if ( retour == 1 ) editCtrl->ChangeValue("="); if ( retour == 2 ) editCtrl->ChangeValue("+"); if ( retour == 3 ) editCtrl->ChangeValue("-"); if ( retour == 4 ) editCtrl->ChangeValue("*"); if ( retour == 5 ) editCtrl->ChangeValue("/"); return; } else if ( metadata.GetType() == "password" ) { GeneratePassword dialog(parent); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.mdp); return; } else if ( metadata.GetType() == "trueorfalse" ) { TrueOrFalse dialog(parent, _("Choose True or False to fill the parameter"), _("True or False")); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(_("True")); else editCtrl->ChangeValue(_("False")); } else if ( metadata.GetType() == "yesorno" ) { if (wxMessageBox(_("Choose yes or no to fullfil parent parameter:"), _("Yes or no") ,wxYES_NO ) == wxYES) editCtrl->ChangeValue(_("yes")); else editCtrl->ChangeValue(_("no")); return; } else if ( metadata.GetType() == "layer" ) { gd::ChooseLayerDialog dialog(parent, layout); if( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetChosenLayer()); return; } else if ( metadata.GetType() == "joyaxis" ) { ChoiceJoyAxis dialog(parent, editCtrl->GetValue(), project, layout); if( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.joyaxis); return; } else if ( metadata.GetType() == "file" ) { ChoiceFile dialog(parent, editCtrl->GetValue(), project, layout); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.file); return; } else if ( metadata.GetType() == "objectvar" ) { if ( paramEdits.empty() ) return; gd::String objectWanted = paramEdits[0]->GetValue(); gd::Object * object = NULL; if ( layout.HasObjectNamed(objectWanted) ) object = &layout.GetObject(objectWanted); else if ( project.HasObjectNamed(objectWanted) ) object = &project.GetObject(objectWanted); else return; gd::ChooseVariableDialog dialog(parent, object->GetVariables()); dialog.SetAssociatedObject(&project, &layout, object); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } else if ( metadata.GetType() == "scenevar" ) { gd::ChooseVariableDialog dialog(parent, layout.GetVariables()); dialog.SetAssociatedLayout(&project, &layout); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } else if ( metadata.GetType() == "globalvar" ) { gd::ChooseVariableDialog dialog(parent, project.GetVariables()); dialog.SetAssociatedProject(&project); if ( dialog.ShowModal() == 1 ) editCtrl->ChangeValue(dialog.GetSelectedVariable()); return; } }
bool ProjectResourcesCopier::CopyAllResourcesTo(gd::Project & originalProject, AbstractFileSystem & fs, gd::String destinationDirectory, bool updateOriginalProject, wxProgressDialog * optionalProgressDialog, bool askAboutAbsoluteFilenames, bool preserveDirectoryStructure) { //Check if there are some resources with absolute filenames gd::ResourcesAbsolutePathChecker absolutePathChecker(fs); originalProject.ExposeResources(absolutePathChecker); bool copyAlsoResourcesWithAbsolutePath = !askAboutAbsoluteFilenames; std::cout << "Copying all ressources to " << destinationDirectory; #if !defined(GD_NO_WX_GUI) if ( !copyAlsoResourcesWithAbsolutePath ) { copyAlsoResourcesWithAbsolutePath = absolutePathChecker.HasResourceWithAbsoluteFilenames() && wxMessageBox(_("Some resources are using absolute filenames.\nDo you want them to be copied in the new folder of the project? If you choose No, they won't be modified."), _("Some resources are using absolute filenames."), wxYES_NO | wxICON_QUESTION) == wxYES; } #endif //Get the resources to be copied gd::ResourcesMergingHelper resourcesMergingHelper(fs); resourcesMergingHelper.SetBaseDirectory(fs.DirNameFrom(originalProject.GetProjectFile())); resourcesMergingHelper.PreserveDirectoriesStructure(preserveDirectoryStructure); resourcesMergingHelper.PreserveAbsoluteFilenames(!copyAlsoResourcesWithAbsolutePath); if ( updateOriginalProject ) { originalProject.ExposeResources(resourcesMergingHelper); } else { std::shared_ptr<gd::Project> project(new gd::Project(originalProject)); project->ExposeResources(resourcesMergingHelper); } //Copy resources map<gd::String, gd::String> & resourcesNewFilename = resourcesMergingHelper.GetAllResourcesOldAndNewFilename(); unsigned int i = 0; for(map<gd::String, gd::String>::const_iterator it = resourcesNewFilename.begin(); it != resourcesNewFilename.end(); ++it) { if ( !it->first.empty() ) { #if !defined(GD_NO_WX_GUI) if ( optionalProgressDialog ) { if ( !optionalProgressDialog->Update(i/static_cast<float>(resourcesNewFilename.size())*100.0f, _("Exporting ")+it->second) ) return false; //User choose to abort. } #endif //Create the destination filename gd::String destinationFile(destinationDirectory + "/" + it->second); fs.MakeAbsolute(destinationFile, destinationDirectory); if ( destinationFile != it->first ) { //Be sure the directory exists gd::String dir = fs.DirNameFrom(destinationFile); if ( !fs.DirExists(dir) ) fs.MkDir(dir); //We can now copy the file if ( !fs.CopyFile(it->first, destinationFile) ) { gd::LogWarning( _( "Unable to copy \"")+it->first+_("\" to \"")+destinationFile+_("\".")); } } } ++i; } return true; }