351 lines
10 KiB
C++
351 lines
10 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "shareduiresources.h"
|
|
#include "../../lib/cbitmap.h"
|
|
#include "../../lib/ccolor.h"
|
|
#include "../../lib/cfileselector.h"
|
|
#include "../../lib/cframe.h"
|
|
#include "../../uidescription/compresseduidescription.h"
|
|
#include "../../uidescription/cstream.h"
|
|
#include "../../uidescription/uiattributes.h"
|
|
#include "../include/ialertbox.h"
|
|
#include "../include/iappdelegate.h"
|
|
#include "../include/iapplication.h"
|
|
#include "../include/helpers/preferences.h"
|
|
#include "application.h"
|
|
#include <unordered_map>
|
|
|
|
//------------------------------------------------------------------------
|
|
namespace VSTGUI {
|
|
namespace Standalone {
|
|
namespace Detail {
|
|
|
|
#if VSTGUI_LIVE_EDITING
|
|
|
|
//------------------------------------------------------------------------
|
|
struct EditFileMap : IEditFileMap
|
|
{
|
|
using Map = std::unordered_map<std::string, std::string>;
|
|
Map fileMap;
|
|
|
|
void set (const std::string& filename, const std::string& absolutePath) override
|
|
{
|
|
fileMap.emplace (filename, absolutePath);
|
|
}
|
|
|
|
Optional<const char*> get (const std::string& filename) const override
|
|
{
|
|
auto it = fileMap.find (filename);
|
|
if (it == fileMap.end ())
|
|
{
|
|
return {};
|
|
}
|
|
return makeOptional (it->second.data ());
|
|
}
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
IEditFileMap& getEditFileMap ()
|
|
{
|
|
static EditFileMap gInstance;
|
|
return gInstance;
|
|
}
|
|
|
|
#endif
|
|
|
|
//------------------------------------------------------------------------
|
|
class SharedUIResources : public ISharedUIResources
|
|
{
|
|
public:
|
|
static SharedUIResources& instance () noexcept;
|
|
|
|
SharedUIResources () noexcept;
|
|
|
|
void cleanup ();
|
|
|
|
Optional<CColor> getColor (const UTF8String& name) const override;
|
|
Optional<CBitmap*> getBitmap (const UTF8String& name) const override;
|
|
Optional<CGradient*> getGradient (const UTF8String& name) const override;
|
|
Optional<CFontDesc*> getFont (const UTF8String& name) const override;
|
|
|
|
SharedPointer<UIDescription> get () const
|
|
{
|
|
load ();
|
|
return uiDesc;
|
|
}
|
|
|
|
private:
|
|
bool load () const;
|
|
|
|
mutable bool loadDone {false};
|
|
mutable SharedPointer<UIDescription> uiDesc;
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
SharedUIResources& SharedUIResources::instance () noexcept
|
|
{
|
|
static SharedUIResources gInstance;
|
|
return gInstance;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
SharedUIResources::SharedUIResources () noexcept
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void SharedUIResources::cleanup ()
|
|
{
|
|
uiDesc = nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
bool SharedUIResources::load () const
|
|
{
|
|
if (loadDone)
|
|
return uiDesc != nullptr;
|
|
loadDone = true;
|
|
if (auto filename = IApplication::instance ().getDelegate ().getSharedUIResourceFilename ())
|
|
{
|
|
|
|
#if VSTGUI_LIVE_EDITING
|
|
if (auto absPath = Detail::getEditFileMap ().get (filename))
|
|
filename = *absPath;
|
|
#endif
|
|
|
|
SharedPointer<UIDescription> description;
|
|
if (Detail::getApplicationPlatformAccess ()
|
|
->getConfiguration ()
|
|
.useCompressedUIDescriptionFiles)
|
|
description = makeOwned<CompressedUIDescription> (filename);
|
|
else
|
|
description = makeOwned<UIDescription> (filename);
|
|
if (!description->parse ())
|
|
{
|
|
#if VSTGUI_LIVE_EDITING
|
|
if (!initUIDescAsNew (*description, nullptr))
|
|
return false;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
auto settings = description->getCustomAttributes ("UIDescFilePath", true);
|
|
auto filePath = settings->getAttributeValue ("path");
|
|
if (filePath)
|
|
description->setFilePath (filePath->data ());
|
|
|
|
uiDesc = std::move (description);
|
|
#if VSTGUI_LIVE_EDITING
|
|
auto res = Detail::checkAndUpdateUIDescFilePath (
|
|
*uiDesc, nullptr, "The resource ui desc file location cannot be found.");
|
|
if (res == UIDescCheckFilePathResult::Cancel)
|
|
{
|
|
IApplication::instance ().quit ();
|
|
return false;
|
|
}
|
|
Detail::getEditFileMap ().set (
|
|
IApplication::instance ().getDelegate ().getSharedUIResourceFilename (),
|
|
uiDesc->getFilePath ());
|
|
if (res == UIDescCheckFilePathResult::NewPathSet)
|
|
saveSharedUIDescription ();
|
|
#endif
|
|
}
|
|
return uiDesc != nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Optional<CColor> SharedUIResources::getColor (const UTF8String& name) const
|
|
{
|
|
if (load ())
|
|
{
|
|
CColor c;
|
|
if (uiDesc->getColor (name, c))
|
|
return makeOptional (c);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Optional<CBitmap*> SharedUIResources::getBitmap (const UTF8String& name) const
|
|
{
|
|
if (load ())
|
|
{
|
|
if (auto bitmap = uiDesc->getBitmap (name))
|
|
{
|
|
return makeOptional (bitmap);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Optional<CGradient*> SharedUIResources::getGradient (const UTF8String& name) const
|
|
{
|
|
if (load ())
|
|
{
|
|
if (auto gradient = uiDesc->getGradient (name))
|
|
{
|
|
return makeOptional (gradient);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
Optional<CFontDesc*> SharedUIResources::getFont (const UTF8String& name) const
|
|
{
|
|
if (load ())
|
|
{
|
|
if (auto font = uiDesc->getFont (name))
|
|
{
|
|
return makeOptional (font);
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
const ISharedUIResources& getSharedUIResources ()
|
|
{
|
|
return SharedUIResources::instance ();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
SharedPointer<UIDescription> getSharedUIDescription ()
|
|
{
|
|
return SharedUIResources::instance ().get ();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void cleanupSharedUIResources ()
|
|
{
|
|
SharedUIResources::instance ().cleanup ();
|
|
}
|
|
|
|
#if VSTGUI_LIVE_EDITING
|
|
//------------------------------------------------------------------------
|
|
static constexpr auto UIDescPathKey = "VSTGUI::Standalone|Debug|UIDescPath|" __FILE__;
|
|
|
|
//------------------------------------------------------------------------
|
|
static void updateUIDescFilePath (const char* path, UIDescription& uiDesc)
|
|
{
|
|
uiDesc.setFilePath (path);
|
|
auto settings = uiDesc.getCustomAttributes ("UIDescFilePath", true);
|
|
settings->setAttribute ("path", uiDesc.getFilePath ());
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
UIDescCheckFilePathResult checkAndUpdateUIDescFilePath (UIDescription& uiDesc, CFrame* _frame,
|
|
UTF8StringPtr notFoundText)
|
|
{
|
|
auto originalPath = std::string (uiDesc.getFilePath ());
|
|
CFileStream stream;
|
|
if (stream.open (originalPath.data (), CFileStream::kReadMode))
|
|
return UIDescCheckFilePathResult::Exists;
|
|
|
|
VSTGUI::Standalone::Preferences prefs;
|
|
auto savedPath = prefs.get (UIDescPathKey);
|
|
if (savedPath)
|
|
{
|
|
unixfyPath (originalPath);
|
|
if (auto uiDescName = lastPathComponent (originalPath))
|
|
{
|
|
auto directory = savedPath->getString ();
|
|
unixfyPath (directory);
|
|
removeLastPathComponent (directory);
|
|
directory += unixPathSeparator;
|
|
directory += *uiDescName;
|
|
if (stream.open (directory.data (), CFileStream::kReadMode))
|
|
{
|
|
updateUIDescFilePath (directory.data (), uiDesc);
|
|
return UIDescCheckFilePathResult::NewPathSet;
|
|
}
|
|
}
|
|
}
|
|
SharedPointer<CFrame> frame (_frame);
|
|
if (!frame)
|
|
frame = makeOwned<CFrame> (CRect (), nullptr);
|
|
|
|
AlertBoxConfig alertConfig;
|
|
alertConfig.headline = notFoundText;
|
|
alertConfig.description = uiDesc.getFilePath ();
|
|
alertConfig.defaultButton = "Locate";
|
|
alertConfig.secondButton = "Close";
|
|
auto alertResult = IApplication::instance ().showAlertBox (alertConfig);
|
|
if (alertResult == AlertResult::SecondButton)
|
|
{
|
|
return UIDescCheckFilePathResult::Cancel;
|
|
}
|
|
auto fs = owned (CNewFileSelector::create (frame, CNewFileSelector::kSelectFile));
|
|
if (savedPath)
|
|
fs->setInitialDirectory (*savedPath);
|
|
fs->setDefaultExtension (CFileExtension ("UIDescription File", "uidesc"));
|
|
fs->setTitle ("Please locate the shared resources uidesc file");
|
|
if (fs->runModal ())
|
|
{
|
|
if (fs->getNumSelectedFiles () == 0)
|
|
{
|
|
return UIDescCheckFilePathResult::Cancel;
|
|
}
|
|
auto path = fs->getSelectedFile (0);
|
|
updateUIDescFilePath (path, uiDesc);
|
|
prefs.set (UIDescPathKey, path);
|
|
return UIDescCheckFilePathResult::NewPathSet;
|
|
}
|
|
return UIDescCheckFilePathResult::Cancel;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
bool initUIDescAsNew (UIDescription& uiDesc, CFrame* _frame)
|
|
{
|
|
SharedPointer<CFrame> frame (_frame);
|
|
if (!frame)
|
|
frame = makeOwned<CFrame> (CRect (), nullptr);
|
|
auto fs = owned (CNewFileSelector::create (frame, CNewFileSelector::kSelectSaveFile));
|
|
vstgui_assert (fs, "create new FileSelector failed");
|
|
VSTGUI::Standalone::Preferences prefs;
|
|
if (auto initPath = prefs.get (UIDescPathKey))
|
|
fs->setInitialDirectory (*initPath);
|
|
fs->setDefaultSaveName (uiDesc.getFilePath ());
|
|
fs->setDefaultExtension (CFileExtension ("UIDescription File", "uidesc"));
|
|
fs->setTitle ("Save UIDescription File");
|
|
if (fs->runModal ())
|
|
{
|
|
if (fs->getNumSelectedFiles () == 0)
|
|
{
|
|
return false;
|
|
}
|
|
auto path = fs->getSelectedFile (0);
|
|
uiDesc.setFilePath (path);
|
|
auto settings = uiDesc.getCustomAttributes ("UIDescFilePath", true);
|
|
settings->setAttribute ("path", path);
|
|
prefs.set (UIDescPathKey, path);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void saveSharedUIDescription ()
|
|
{
|
|
if (auto uiDesc = getSharedUIDescription ())
|
|
{
|
|
int32_t flags = UIDescription::kWriteImagesIntoUIDescFile |
|
|
CompressedUIDescription::kForceWriteCompressedDesc;
|
|
if (uiDesc->save (uiDesc->getFilePath (), flags))
|
|
return;
|
|
AlertBoxConfig config;
|
|
config.headline = "Saving the shared resources uidesc file failed.";
|
|
IApplication::instance ().showAlertBox (config);
|
|
}
|
|
}
|
|
|
|
#endif // VSTGUI_LIVE_EDITING
|
|
|
|
//------------------------------------------------------------------------
|
|
} // Detail
|
|
} // Standalone
|
|
} // VSTGUI
|