/* * GDevelop Core * Copyright 2008-2015 Florian Rival (Florian.Rival@gmail.com). All rights reserved. * This project is released under the MIT License. */ #include #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) #include "GDCore/IDE/wxTools/CommonBitmapProvider.h" #include #include #include #include #include #endif #include "GDCore/Project/Project.h" #include "GDCore/Project/ResourcesManager.h" #include "GDCore/CommonTools.h" #include "GDCore/Serialization/Serializer.h" #include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Tools/Log.h" #include "GDCore/Tools/Localization.h" namespace gd { gd::String Resource::badStr; Resource ResourcesManager::badResource; #if defined(GD_IDE_ONLY) ResourceFolder ResourcesManager::badFolder; Resource ResourceFolder::badResource; #endif #if defined(GD_IDE_ONLY) void ResourceFolder::Init(const ResourceFolder & other) { name = other.name; resources.clear(); for (std::size_t i = 0;i(other.resources[i]->Clone())); } } #endif void ResourcesManager::Init(const ResourcesManager & other) { resources.clear(); for (std::size_t i = 0;i(other.resources[i]->Clone())); } #if defined(GD_IDE_ONLY) folders.clear(); for (std::size_t i = 0;iGetName() == name ) return *resources[i]; } return badResource; } const Resource & ResourcesManager::GetResource(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return *resources[i]; } return badResource; } std::shared_ptr ResourcesManager::CreateResource(const gd::String & kind) { if (kind == "image") { return std::shared_ptr(new ImageResource); } std::cout << "Bad resource created ( type: " << kind << ")" << std::endl; return std::shared_ptr(new Resource); } bool ResourcesManager::HasResource(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return true; } return false; } std::vector ResourcesManager::GetAllResourcesList() { std::vector allResources; for (std::size_t i = 0;iGetName()); return allResources; } #if defined(GD_IDE_ONLY) bool ResourcesManager::AddResource(const gd::Resource & resource) { if ( HasResource(resource.GetName()) ) return false; try { const Resource & castedResource = dynamic_cast(resource); std::shared_ptr newResource = std::shared_ptr(castedResource.Clone()); if ( newResource == std::shared_ptr() ) return false; resources.push_back(newResource); } catch(...) { std::cout << "WARNING: Tried to add a resource which is not a GD C++ Platform Resource to a GD C++ Platform project"; std::cout << char(7); } return true; } bool ResourcesManager::AddResource(const gd::String & name, const gd::String & filename) { if ( HasResource(name) ) return false; std::shared_ptr image(new ImageResource); image->SetFile(filename); image->SetName(name); resources.push_back(image); return true; } std::vector ResourceFolder::GetAllResourcesList() { std::vector allResources; for (std::size_t i = 0;iGetName()); return allResources; } bool ImageResource::EditProperty(gd::Project & project, const gd::String & property) { return false; } bool ImageResource::ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue) { if ( property == "smooth" ) smooth = (newValue == _("Yes")); else if ( property == "alwaysLoaded" ) alwaysLoaded = (newValue == _("Yes")); return true; } void ImageResource::GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const { if ( property == "smooth" ) { userFriendlyName = _("Smooth the image"); description = _("Set this to \"Yes\" to set a smooth filter on the image"); } else if ( property == "alwaysLoaded" ) { userFriendlyName = _("Always loaded in memory"); description = _("Set this to \"Yes\" to let the image always loaded in memory.\nUseful when the image is used by actions."); } } gd::String ImageResource::GetProperty(gd::Project & project, const gd::String & property) { if ( property == "smooth" ) { return smooth ? _("Yes") : _("No"); } else if ( property == "alwaysLoaded" ) { return alwaysLoaded ? _("Yes") : _("No"); } return ""; } /** * Return a vector containing the name of all the properties of the resource */ std::vector ImageResource::GetAllProperties(gd::Project & project) const { std::vector allProperties; allProperties.push_back("smooth"); allProperties.push_back("alwaysLoaded"); return allProperties; } #if !defined(GD_NO_WX_GUI) void ImageResource::RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & project) { wxLogNull noLog; //We take care of errors. wxSize size = previewPanel.GetSize(); //Checkerboard background dc.SetBrush(gd::CommonBitmapProvider::Get()->transparentBg); dc.DrawRectangle(0,0, size.GetWidth(), size.GetHeight()); wxString fullFilename = GetAbsoluteFile(project); if ( !wxFile::Exists(fullFilename) ) return; wxBitmap bmp( fullFilename, wxBITMAP_TYPE_ANY); if ( bmp.GetWidth() != 0 && bmp.GetHeight() != 0 && (bmp.GetWidth() > previewPanel.GetSize().x || bmp.GetHeight() > previewPanel.GetSize().y) ) { //Rescale to fit in previewPanel float xFactor = static_cast(previewPanel.GetSize().x)/static_cast(bmp.GetWidth()); float yFactor = static_cast(previewPanel.GetSize().y)/static_cast(bmp.GetHeight()); float factor = std::min(xFactor, yFactor); wxImage image = bmp.ConvertToImage(); if ( bmp.GetWidth()*factor >= 5 && bmp.GetHeight()*factor >= 5) bmp = wxBitmap(image.Scale(bmp.GetWidth()*factor, bmp.GetHeight()*factor)); } //Display image in the center if ( bmp.IsOk() ) dc.DrawBitmap(bmp, (size.GetWidth() - bmp.GetWidth()) / 2, (size.GetHeight() - bmp.GetHeight()) / 2, true /* use mask */); } #endif Resource & ResourceFolder::GetResource(const gd::String & name) { for (std::size_t i = 0;iGetName() == name ) return *resources[i]; } return badResource; } const Resource & ResourceFolder::GetResource(const gd::String & name) const { for (std::size_t i = 0;iGetName() == name ) return *resources[i]; } return badResource; } namespace { bool MoveResourceUpInList(std::vector< std::shared_ptr > & resources, const gd::String & name) { std::size_t index = gd::String::npos; for (std::size_t i = 0;iGetName() == name) { index = i; break; } } if ( index < resources.size() && index > 0 ) { swap (resources[index], resources[index-1]); return true; } return false; } bool MoveResourceDownInList(std::vector< std::shared_ptr > & resources, const gd::String & name) { std::size_t index = gd::String::npos; for (std::size_t i = 0;iGetName() == name) { index = i; break; } } if ( index < resources.size()-1 ) { swap (resources[index], resources[index+1]); return true; } return false; } } 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 ResourceFolder::MoveResourceUpInList(const gd::String & name) { return gd::MoveResourceUpInList(resources, name); } bool ResourceFolder::MoveResourceDownInList(const gd::String & name) { return gd::MoveResourceDownInList(resources, name); } bool ResourcesManager::MoveResourceUpInList(const gd::String & name) { return gd::MoveResourceUpInList(resources, name); } bool ResourcesManager::MoveResourceDownInList(const gd::String & name) { return gd::MoveResourceDownInList(resources, name); } bool ResourcesManager::MoveFolderUpInList(const gd::String & name) { for (std::size_t i =1;i ResourcesManager::GetResourceSPtr(const gd::String & name) { for (std::size_t i = 0;iGetName() == name ) return resources[i]; } return std::shared_ptr(); } bool ResourcesManager::HasFolder(const gd::String & name) const { for (std::size_t i = 0;i ResourcesManager::GetAllFolderList() { std::vector allFolders; for (std::size_t i =0;iGetName() == name ) return true; } return false; } void ResourceFolder::AddResource(const gd::String & name, gd::ResourcesManager & parentManager) { try { ResourcesManager & manager = dynamic_cast(parentManager); std::shared_ptr resource = std::dynamic_pointer_cast(manager.GetResourceSPtr(name)); if ( resource != std::shared_ptr()) resources.push_back(resource); } catch(...) { std::cout << "Warning: A resources manager which is not part of GD C++ Platform was used during call to AddResource" << std::endl; } } void ResourcesManager::RenameResource(const gd::String & oldName, const gd::String & newName) { for (std::size_t i = 0;iGetName() == oldName ) resources[i]->SetName(newName); } } void ResourceFolder::RemoveResource(const gd::String & name) { for (std::size_t i = 0;i() && resources[i]->GetName() == name) resources.erase(resources.begin()+i); else ++i; } } void ResourcesManager::RemoveResource(const gd::String & name) { for (std::size_t i = 0;i() && resources[i]->GetName() == name) resources.erase(resources.begin()+i); else ++i; } for (std::size_t i = 0;i() ) continue; resourcesElement.AddChild("resource").SetAttribute("name", resources[i]->GetName()); } } #endif void ResourcesManager::UnserializeFrom(const SerializerElement & element) { const SerializerElement & resourcesElement = element.GetChild("resources", 0, "Resources"); resourcesElement.ConsiderAsArrayOf("resource", "Resource"); for(std::size_t i = 0;i resource = CreateResource(kind); resource->SetName(name); resource->UnserializeFrom(resourceElement); resources.push_back(resource); } #if defined(GD_IDE_ONLY) const SerializerElement & resourcesFoldersElement = element.GetChild("resourceFolders", 0, "ResourceFolders"); resourcesFoldersElement.ConsiderAsArrayOf("folder", "Folder"); for(std::size_t i = 0;i() ) break; SerializerElement & resourceElement = resourcesElement.AddChild("resource"); resourceElement.SetAttribute("kind", resources[i]->GetKind()); resourceElement.SetAttribute("name", resources[i]->GetName()); resources[i]->SerializeTo(resourceElement); } SerializerElement & resourcesFoldersElement = element.AddChild("resourceFolders"); resourcesFoldersElement.ConsiderAsArrayOf("folder"); for (std::size_t i = 0;i