1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Projucer: Enforce that Icons instances are created from files

This commit is contained in:
reuk 2025-07-22 12:15:00 +01:00
parent 217e7ab444
commit cfbe853f69
No known key found for this signature in database
7 changed files with 59 additions and 55 deletions

View file

@ -35,22 +35,28 @@
namespace juce::build_tools namespace juce::build_tools
{ {
Array<Drawable*> asArray (const Icons& icons) Icons Icons::fromFilesSmallAndBig (const File& small, const File& big)
{ {
Array<Drawable*> result; Icons result;
result.small = Drawable::createFromImageFile (small);
result.big = Drawable::createFromImageFile (big);
return result;
}
if (icons.small != nullptr) Array<const Drawable*> asArray (const Icons& icons)
result.add (icons.small.get()); {
Array<const Drawable*> result;
if (icons.big != nullptr) for (auto getter : { &Icons::getSmall, &Icons::getBig })
result.add (icons.big.get()); if (auto* got = (icons.*getter)())
result.add (got);
return result; return result;
} }
namespace mac namespace mac
{ {
static Image fixIconImageSize (Drawable& image) static Image fixIconImageSize (const Drawable& image)
{ {
const int validSizes[] = { 16, 32, 64, 128, 256, 512, 1024 }; const int validSizes[] = { 16, 32, 64, 128, 256, 512, 1024 };
@ -90,7 +96,7 @@ namespace juce::build_tools
{ {
MemoryOutputStream data; MemoryOutputStream data;
auto smallest = std::numeric_limits<int>::max(); auto smallest = std::numeric_limits<int>::max();
Drawable* smallestImage = nullptr; const Drawable* smallestImage = nullptr;
const auto images = asArray (icons); const auto images = asArray (icons);
@ -134,25 +140,25 @@ namespace juce::build_tools
int size, int size,
bool returnNullIfNothingBigEnough) bool returnNullIfNothingBigEnough)
{ {
auto* const im = [&]() -> Drawable* auto* const im = std::invoke ([&]() -> const Drawable*
{ {
if ((icons.small != nullptr) != (icons.big != nullptr)) if ((icons.getSmall() != nullptr) != (icons.getBig() != nullptr))
return icons.small != nullptr ? icons.small.get() : icons.big.get(); return icons.getSmall() != nullptr ? icons.getSmall() : icons.getBig();
if (icons.small != nullptr && icons.big != nullptr) if (icons.getSmall() != nullptr && icons.getBig() != nullptr)
{ {
if (icons.small->getWidth() >= size && icons.big->getWidth() >= size) if (icons.getSmall()->getWidth() >= size && icons.getBig()->getWidth() >= size)
return icons.small->getWidth() < icons.big->getWidth() ? icons.small.get() : icons.big.get(); return icons.getSmall()->getWidth() < icons.getBig()->getWidth() ? icons.getSmall() : icons.getBig();
if (icons.small->getWidth() >= size) if (icons.getSmall()->getWidth() >= size)
return icons.small.get(); return icons.getSmall();
if (icons.big->getWidth() >= size) if (icons.getBig()->getWidth() >= size)
return icons.big.get(); return icons.getBig();
} }
return nullptr; return nullptr;
}(); });
if (im == nullptr) if (im == nullptr)
return {}; return {};
@ -304,9 +310,9 @@ namespace juce::build_tools
writeStreamToFile (file, [&] (MemoryOutputStream& mo) { writeWinIcon (icons, mo); }); writeStreamToFile (file, [&] (MemoryOutputStream& mo) { writeWinIcon (icons, mo); });
} }
Image rescaleImageForIcon (Drawable& d, const int size) Image rescaleImageForIcon (const Drawable& d, const int size)
{ {
if (auto* drawableImage = dynamic_cast<DrawableImage*> (&d)) if (auto* drawableImage = dynamic_cast<const DrawableImage*> (&d))
{ {
auto im = SoftwareImageType().convert (drawableImage->getImage()); auto im = SoftwareImageType().convert (drawableImage->getImage());
@ -365,8 +371,8 @@ namespace juce::build_tools
static void createiOSIconFiles (const Icons& icons, File appIconSet) static void createiOSIconFiles (const Icons& icons, File appIconSet)
{ {
auto* imageToUse = icons.big != nullptr ? icons.big.get() auto* imageToUse = icons.getBig() != nullptr ? icons.getBig()
: icons.small.get(); : icons.getSmall();
if (imageToUse != nullptr) if (imageToUse != nullptr)
{ {

View file

@ -35,20 +35,29 @@
namespace juce::build_tools namespace juce::build_tools
{ {
struct Icons class Icons
{ {
public:
Icons() = default;
static Icons fromFilesSmallAndBig (const File& small, const File& big);
const Drawable* getSmall() const { return small.get(); }
const Drawable* getBig() const { return big.get(); }
private:
std::unique_ptr<Drawable> small; std::unique_ptr<Drawable> small;
std::unique_ptr<Drawable> big; std::unique_ptr<Drawable> big;
}; };
Array<Drawable*> asArray (const Icons&); Array<const Drawable*> asArray (const Icons&);
void writeMacIcon (const Icons&, const File&); void writeMacIcon (const Icons&, const File&);
void writeWinIcon (const Icons&, const File&); void writeWinIcon (const Icons&, const File&);
Image getBestIconForSize (const Icons& icons, Image getBestIconForSize (const Icons& icons,
int size, int size,
bool returnNullIfNothingBigEnough); bool returnNullIfNothingBigEnough);
Image rescaleImageForIcon (Drawable& d, int size); Image rescaleImageForIcon (const Drawable& d, int size);
RelativePath createXcassetsFolderFromIcons (const Icons& icons, RelativePath createXcassetsFolderFromIcons (const Icons& icons,
const File& targetFolder, const File& targetFolder,

View file

@ -124,19 +124,18 @@ IconParseResults parseIconArguments (juce::ArgumentList&& args)
args.checkMinNumArguments (2); args.checkMinNumArguments (2);
const auto output = args.arguments.removeAndReturn (0); const auto output = args.arguments.removeAndReturn (0);
const auto popDrawable = [&args]() -> std::unique_ptr<juce::Drawable> const auto popFile = [&args]() -> juce::File
{ {
if (args.size() == 0) if (args.size() == 0)
return {}; return {};
const auto firstArgText = args.arguments.removeAndReturn (0).text; return args.arguments.removeAndReturn (0).text;
return juce::Drawable::createFromImageFile (firstArgText);
}; };
auto smallIcon = popDrawable(); const auto smallIcon = popFile();
auto bigIcon = popDrawable(); const auto bigIcon = popFile();
return { { std::move (smallIcon), std::move (bigIcon) }, output.text }; return { juce::build_tools::Icons::fromFilesSmallAndBig (smallIcon, bigIcon), output.text };
} }
int writeMacIcon (juce::ArgumentList&& argumentList) int writeMacIcon (juce::ArgumentList&& argumentList)

View file

@ -1632,19 +1632,6 @@ Project::Item Project::Item::createCopy() { Item i (*this); i.state = i.
String Project::Item::getID() const { return state [Ids::ID]; } String Project::Item::getID() const { return state [Ids::ID]; }
void Project::Item::setID (const String& newID) { state.setProperty (Ids::ID, newID, nullptr); } void Project::Item::setID (const String& newID) { state.setProperty (Ids::ID, newID, nullptr); }
std::unique_ptr<Drawable> Project::Item::loadAsImageFile() const
{
const MessageManagerLock mml (ThreadPoolJob::getCurrentThreadPoolJob());
if (! mml.lockWasGained())
return nullptr;
if (isValid())
return Drawable::createFromImageFile (getFile());
return {};
}
Project::Item Project::Item::createGroup (Project& project, const String& name, const String& uid, bool isModuleCode) Project::Item Project::Item::createGroup (Project& project, const String& name, const String& uid, bool isModuleCode)
{ {
Item group (project, ValueTree (Ids::GROUP), isModuleCode); Item group (project, ValueTree (Ids::GROUP), isModuleCode);

View file

@ -453,9 +453,6 @@ public:
void setID (const String& newID); void setID (const String& newID);
Item findItemWithID (const String& targetId) const; // (recursive search) Item findItemWithID (const String& targetId) const; // (recursive search)
String getImageFileID() const;
std::unique_ptr<Drawable> loadAsImageFile() const;
//============================================================================== //==============================================================================
Value getNameValue(); Value getNameValue();
String getName() const; String getName() const;

View file

@ -1424,15 +1424,15 @@ private:
{ {
const auto icons = getIcons(); const auto icons = getIcons();
if (icons.big != nullptr && icons.small != nullptr) if (icons.getBig() != nullptr && icons.getSmall() != nullptr)
{ {
auto step = jmax (icons.big->getWidth(), icons.big->getHeight()) / 8; auto step = jmax (icons.getBig()->getWidth(), icons.getBig()->getHeight()) / 8;
writeIcon (folder.getChildFile ("drawable-xhdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 8, false)); writeIcon (folder.getChildFile ("drawable-xhdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 8, false));
writeIcon (folder.getChildFile ("drawable-hdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 6, false)); writeIcon (folder.getChildFile ("drawable-hdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 6, false));
writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 4, false)); writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::getBestIconForSize (icons, step * 4, false));
writeIcon (folder.getChildFile ("drawable-ldpi/icon.png"), build_tools::getBestIconForSize (icons, step * 3, false)); writeIcon (folder.getChildFile ("drawable-ldpi/icon.png"), build_tools::getBestIconForSize (icons, step * 3, false));
} }
else if (auto* icon = (icons.big != nullptr ? icons.big.get() : icons.small.get())) else if (auto* icon = (icons.getBig() != nullptr ? icons.getBig() : icons.getSmall()))
{ {
writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::rescaleImageForIcon (*icon, icon->getWidth())); writeIcon (folder.getChildFile ("drawable-mdpi/icon.png"), build_tools::rescaleImageForIcon (*icon, icon->getWidth()));
} }
@ -1829,7 +1829,7 @@ private:
{ {
const auto icons = getIcons(); const auto icons = getIcons();
if (icons.big != nullptr || icons.small != nullptr) if (icons.getBig() != nullptr || icons.getSmall() != nullptr)
app->setAttribute ("android:icon", "@drawable/icon"); app->setAttribute ("android:icon", "@drawable/icon");
} }

View file

@ -869,12 +869,18 @@ void ProjectExporter::createDefaultConfigs()
build_tools::Icons ProjectExporter::getIcons() const build_tools::Icons ProjectExporter::getIcons() const
{ {
const auto loadIcon = [this] (auto id) const MessageManagerLock mml (ThreadPoolJob::getCurrentThreadPoolJob());
if (! mml.lockWasGained())
return {};
const auto getFile = [this] (auto id)
{ {
return project.getMainGroup().findItemWithID (settings[id]).loadAsImageFile(); return project.getMainGroup().findItemWithID (settings[id]).getFile();
}; };
return { loadIcon (Ids::smallIcon), loadIcon (Ids::bigIcon) }; return build_tools::Icons::fromFilesSmallAndBig (getFile (Ids::smallIcon),
getFile (Ids::bigIcon));
} }
//============================================================================== //==============================================================================