mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Projucer: The GUI editor now generates paint code containing extra variables for the coordinates, so that these can be overridden individually in custom code blocks
This commit is contained in:
parent
457e838971
commit
730e603b02
21 changed files with 503 additions and 305 deletions
|
|
@ -93,6 +93,11 @@ bool ComponentDocument::loadFromXml (const XmlElement& xml)
|
|||
return false;
|
||||
}
|
||||
|
||||
void ComponentDocument::applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
backgroundGraphics->applyCustomPaintSnippets (snippets);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class NormalTestComponent : public Component
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
bool loadFromXml (const XmlElement& xml);
|
||||
|
||||
void fillInGeneratedCode (GeneratedCode& code) const;
|
||||
void applyCustomPaintSnippets (StringArray&);
|
||||
|
||||
private:
|
||||
ScopedPointer<ComponentLayout> components;
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ static void copyAcrossUserSections (String& dest, const String& src)
|
|||
{
|
||||
StringArray sourceLines;
|
||||
|
||||
if (getUserSection (srcLines, tag, sourceLines))
|
||||
if (tag != "UserPaintCustomArguments" && getUserSection (srcLines, tag, sourceLines))
|
||||
{
|
||||
for (int j = endLine - i; --j > 0;)
|
||||
dstLines.remove (i + 1);
|
||||
|
|
|
|||
|
|
@ -42,14 +42,7 @@ const char* const defaultParentClasses = "public Component";
|
|||
JucerDocument::JucerDocument (SourceCodeDocument* c)
|
||||
: cpp (c),
|
||||
className (defaultClassName),
|
||||
parentClasses (defaultParentClasses),
|
||||
fixedSize (false),
|
||||
initialWidth (600),
|
||||
initialHeight (400),
|
||||
snapGridPixels (8),
|
||||
snapActive (true),
|
||||
snapShown (true),
|
||||
componentOverlayOpacity (0.33f)
|
||||
parentClasses (defaultParentClasses)
|
||||
{
|
||||
jassert (cpp != nullptr);
|
||||
resources.setDocument (this);
|
||||
|
|
@ -599,13 +592,49 @@ bool JucerDocument::reloadFromDocument()
|
|||
|
||||
resources.loadFromCpp (getCppFile(), cppContent);
|
||||
|
||||
return loadFromXml (*currentXML);
|
||||
bool result = loadFromXml (*currentXML);
|
||||
extractCustomPaintSnippetsFromCppFile (cppContent);
|
||||
return result;
|
||||
}
|
||||
|
||||
void JucerDocument::refreshCustomCodeFromDocument()
|
||||
{
|
||||
const String cppContent (cpp->getCodeDocument().getAllContent());
|
||||
extractCustomPaintSnippetsFromCppFile (cppContent);
|
||||
}
|
||||
|
||||
void JucerDocument::extractCustomPaintSnippetsFromCppFile (const String& cppContent)
|
||||
{
|
||||
StringArray customPaintSnippets;
|
||||
|
||||
auto lines = StringArray::fromLines (cppContent);
|
||||
int last = 0;
|
||||
|
||||
while (last >= 0)
|
||||
{
|
||||
const int start = indexOfLineStartingWith (lines, "//[UserPaintCustomArguments]", last);
|
||||
if (start < 0)
|
||||
break;
|
||||
|
||||
const int end = indexOfLineStartingWith (lines, "//[/UserPaintCustomArguments]", start);
|
||||
if (end < 0)
|
||||
break;
|
||||
|
||||
last = end + 1;
|
||||
String result;
|
||||
|
||||
for (int i = start + 1; i < end; ++i)
|
||||
result << lines [i] << newLine;
|
||||
|
||||
customPaintSnippets.add (CodeHelpers::unindent (result, 4));
|
||||
}
|
||||
|
||||
applyCustomPaintSnippets (customPaintSnippets);
|
||||
}
|
||||
|
||||
XmlElement* JucerDocument::pullMetaDataFromCppFile (const String& cpp)
|
||||
{
|
||||
StringArray lines;
|
||||
lines.addLines (cpp);
|
||||
auto lines = StringArray::fromLines (cpp);
|
||||
|
||||
const int startLine = indexOfLineStartingWith (lines, "BEGIN_JUCER_METADATA", 0);
|
||||
|
||||
|
|
@ -624,17 +653,15 @@ XmlElement* JucerDocument::pullMetaDataFromCppFile (const String& cpp)
|
|||
bool JucerDocument::isValidJucerCppFile (const File& f)
|
||||
{
|
||||
if (f.hasFileExtension (".cpp"))
|
||||
{
|
||||
const ScopedPointer<XmlElement> xml (pullMetaDataFromCppFile (f.loadFileAsString()));
|
||||
return xml != nullptr && xml->hasTagName (jucerCompXmlTag);
|
||||
}
|
||||
if (ScopedPointer<XmlElement> xml = pullMetaDataFromCppFile (f.loadFileAsString()))
|
||||
return xml->hasTagName (jucerCompXmlTag);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static JucerDocument* createDocument (SourceCodeDocument* cpp)
|
||||
{
|
||||
CodeDocument& codeDoc = cpp->getCodeDocument();
|
||||
auto& codeDoc = cpp->getCodeDocument();
|
||||
|
||||
ScopedPointer<XmlElement> xml (JucerDocument::pullMetaDataFromCppFile (codeDoc.getAllContent()));
|
||||
|
||||
|
|
@ -684,9 +711,9 @@ public:
|
|||
|
||||
bool saveHeader()
|
||||
{
|
||||
OpenDocumentManager& odm = ProjucerApplication::getApp().openDocumentManager;
|
||||
auto& odm = ProjucerApplication::getApp().openDocumentManager;
|
||||
|
||||
if (OpenDocumentManager::Document* header = odm.openFile (nullptr, getFile().withFileExtension (".h")))
|
||||
if (auto* header = odm.openFile (nullptr, getFile().withFileExtension (".h")))
|
||||
return header->save();
|
||||
|
||||
return false;
|
||||
|
|
@ -694,9 +721,7 @@ public:
|
|||
|
||||
Component* createEditor() override
|
||||
{
|
||||
ScopedPointer<JucerDocument> jucerDoc (JucerDocument::createForCppFile (getProject(), getFile()));
|
||||
|
||||
if (jucerDoc != nullptr)
|
||||
if (ScopedPointer<JucerDocument> jucerDoc = JucerDocument::createForCppFile (getProject(), getFile()))
|
||||
return new JucerDocumentEditor (jucerDoc.release());
|
||||
|
||||
return SourceCodeDocument::createEditor();
|
||||
|
|
@ -736,15 +761,13 @@ public:
|
|||
headerFile.replaceWithText (String());
|
||||
cppFile.replaceWithText (String());
|
||||
|
||||
OpenDocumentManager& odm = ProjucerApplication::getApp().openDocumentManager;
|
||||
auto& odm = ProjucerApplication::getApp().openDocumentManager;
|
||||
|
||||
if (SourceCodeDocument* cpp = dynamic_cast<SourceCodeDocument*> (odm.openFile (nullptr, cppFile)))
|
||||
if (auto* cpp = dynamic_cast<SourceCodeDocument*> (odm.openFile (nullptr, cppFile)))
|
||||
{
|
||||
if (SourceCodeDocument* header = dynamic_cast<SourceCodeDocument*> (odm.openFile (nullptr, headerFile)))
|
||||
if (auto* header = dynamic_cast<SourceCodeDocument*> (odm.openFile (nullptr, headerFile)))
|
||||
{
|
||||
ScopedPointer<JucerDocument> jucerDoc (new ComponentDocument (cpp));
|
||||
|
||||
if (jucerDoc != nullptr)
|
||||
if (ScopedPointer<JucerDocument> jucerDoc = new ComponentDocument (cpp))
|
||||
{
|
||||
jucerDoc->setClassName (newFile.getFileNameWithoutExtension());
|
||||
|
||||
|
|
|
|||
|
|
@ -136,14 +136,17 @@ public:
|
|||
|
||||
static bool shouldUseTransMacro() noexcept { return true; }
|
||||
|
||||
//==============================================================================
|
||||
void refreshCustomCodeFromDocument();
|
||||
|
||||
protected:
|
||||
SourceCodeDocument* cpp;
|
||||
|
||||
String className, componentName, templateFile;
|
||||
String parentClasses, constructorParams, variableInitialisers;
|
||||
|
||||
bool fixedSize;
|
||||
int initialWidth, initialHeight;
|
||||
bool fixedSize = false;
|
||||
int initialWidth = 600, initialHeight = 400;
|
||||
|
||||
BinaryResources resources;
|
||||
|
||||
|
|
@ -153,6 +156,8 @@ protected:
|
|||
virtual void fillInGeneratedCode (GeneratedCode&) const;
|
||||
virtual void fillInPaintCode (GeneratedCode&) const;
|
||||
|
||||
virtual void applyCustomPaintSnippets (StringArray&) {}
|
||||
|
||||
static void addMethod (const String& base, const String& returnVal,
|
||||
const String& method, const String& initialContent,
|
||||
StringArray& baseClasses, StringArray& returnValues,
|
||||
|
|
@ -160,9 +165,9 @@ protected:
|
|||
|
||||
private:
|
||||
UndoManager undoManager;
|
||||
int snapGridPixels;
|
||||
bool snapActive, snapShown;
|
||||
float componentOverlayOpacity;
|
||||
int snapGridPixels = 8;
|
||||
bool snapActive = true, snapShown = true;
|
||||
float componentOverlayOpacity = 0.33f;
|
||||
StringArray activeExtraMethods;
|
||||
ScopedPointer<XmlElement> currentXML;
|
||||
ScopedPointer<Timer> userDocChangeTimer;
|
||||
|
|
@ -172,6 +177,7 @@ private:
|
|||
void codeDocumentTextDeleted (int startIndex, int endIndex) override;
|
||||
void userEditedCpp();
|
||||
bool documentAboutToClose (OpenDocumentManager::Document*) override;
|
||||
void extractCustomPaintSnippetsFromCppFile (const String& cpp);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JucerDocument)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -293,16 +293,9 @@ void PaintRoutine::copySelectedToClipboard()
|
|||
|
||||
XmlElement clip (clipboardXmlTag);
|
||||
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
{
|
||||
PaintElement* const pe = elements.getUnchecked(i);
|
||||
|
||||
for (auto* pe : elements)
|
||||
if (selectedElements.isSelected (pe))
|
||||
{
|
||||
XmlElement* const e = pe->createXml();
|
||||
clip.addChildElement (e);
|
||||
}
|
||||
}
|
||||
clip.addChildElement (pe->createXml());
|
||||
|
||||
SystemClipboard::copyTextToClipboard (clip.createDocument ("", false, false));
|
||||
}
|
||||
|
|
@ -325,8 +318,8 @@ void PaintRoutine::paste()
|
|||
|
||||
void PaintRoutine::deleteSelected()
|
||||
{
|
||||
const SelectedItemSet <PaintElement*> temp1 (selectedElements);
|
||||
const SelectedItemSet <PathPoint*> temp2 (selectedPoints);
|
||||
const SelectedItemSet<PaintElement*> temp1 (selectedElements);
|
||||
const SelectedItemSet<PathPoint*> temp2 (selectedPoints);
|
||||
|
||||
if (temp2.getNumSelected() > 0)
|
||||
{
|
||||
|
|
@ -369,7 +362,7 @@ void PaintRoutine::selectAll()
|
|||
|
||||
void PaintRoutine::selectedToFront()
|
||||
{
|
||||
const SelectedItemSet <PaintElement*> temp (selectedElements);
|
||||
const SelectedItemSet<PaintElement*> temp (selectedElements);
|
||||
|
||||
for (int i = temp.getNumSelected(); --i >= 0;)
|
||||
elementToFront (temp.getSelectedItem(i), true);
|
||||
|
|
@ -377,7 +370,7 @@ void PaintRoutine::selectedToFront()
|
|||
|
||||
void PaintRoutine::selectedToBack()
|
||||
{
|
||||
const SelectedItemSet <PaintElement*> temp (selectedElements);
|
||||
const SelectedItemSet<PaintElement*> temp (selectedElements);
|
||||
|
||||
for (int i = 0; i < temp.getNumSelected(); ++i)
|
||||
elementToBack (temp.getSelectedItem(i), true);
|
||||
|
|
@ -399,11 +392,9 @@ void PaintRoutine::ungroupSelected()
|
|||
|
||||
void PaintRoutine::bringLostItemsBackOnScreen (const Rectangle<int>& parentArea)
|
||||
{
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
for (auto* c : elements)
|
||||
{
|
||||
PaintElement* const c = elements[i];
|
||||
|
||||
Rectangle<int> r (c->getCurrentBounds (parentArea));
|
||||
auto r = c->getCurrentBounds (parentArea);
|
||||
|
||||
if (! r.intersects (parentArea))
|
||||
{
|
||||
|
|
@ -415,11 +406,9 @@ void PaintRoutine::bringLostItemsBackOnScreen (const Rectangle<int>& parentArea)
|
|||
|
||||
void PaintRoutine::startDragging (const Rectangle<int>& parentArea)
|
||||
{
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
for (auto* c : elements)
|
||||
{
|
||||
PaintElement* const c = elements[i];
|
||||
|
||||
Rectangle<int> r (c->getCurrentBounds (parentArea));
|
||||
auto r = c->getCurrentBounds (parentArea);
|
||||
|
||||
c->getProperties().set ("xDragStart", r.getX());
|
||||
c->getProperties().set ("yDragStart", r.getY());
|
||||
|
|
@ -490,8 +479,8 @@ void PaintRoutine::drawElements (Graphics& g, const Rectangle<int>& relativeTo)
|
|||
Component temp;
|
||||
temp.setBounds (relativeTo);
|
||||
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
elements.getUnchecked (i)->draw (g, getDocument()->getComponentLayout(), relativeTo);
|
||||
for (auto* e : elements)
|
||||
e->draw (g, getDocument()->getComponentLayout(), relativeTo);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -501,17 +490,16 @@ void PaintRoutine::dropImageAt (const File& f, int x, int y)
|
|||
|
||||
if (d != nullptr)
|
||||
{
|
||||
Rectangle<float> bounds (d->getDrawableBounds());
|
||||
auto bounds = d->getDrawableBounds();
|
||||
d = nullptr;
|
||||
|
||||
PaintElement* newElement
|
||||
= addNewElement (ObjectTypes::createNewImageElement (this), -1, true);
|
||||
auto* newElement = addNewElement (ObjectTypes::createNewImageElement (this), -1, true);
|
||||
|
||||
if (PaintElementImage* pei = dynamic_cast<PaintElementImage*> (newElement))
|
||||
if (auto* pei = dynamic_cast<PaintElementImage*> (newElement))
|
||||
{
|
||||
String resourceName (getDocument()->getResources().findUniqueName (f.getFileName()));
|
||||
|
||||
if (const BinaryResources::BinaryResource* existingResource = getDocument()->getResources().getResourceForFile (f))
|
||||
if (auto* existingResource = getDocument()->getResources().getResourceForFile (f))
|
||||
{
|
||||
resourceName = existingResource->name;
|
||||
}
|
||||
|
|
@ -546,12 +534,11 @@ const char* PaintRoutine::xmlTagName = "BACKGROUND";
|
|||
|
||||
XmlElement* PaintRoutine::createXml() const
|
||||
{
|
||||
XmlElement* const xml = new XmlElement (xmlTagName);
|
||||
|
||||
auto* xml = new XmlElement (xmlTagName);
|
||||
xml->setAttribute ("backgroundColour", backgroundColour.toString());
|
||||
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
xml->addChildElement (elements.getUnchecked (i)->createXml());
|
||||
for (auto* e : elements)
|
||||
xml->addChildElement (e->createXml());
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
|
@ -565,7 +552,7 @@ bool PaintRoutine::loadFromXml (const XmlElement& xml)
|
|||
clear();
|
||||
|
||||
forEachXmlChildElement (xml, e)
|
||||
if (PaintElement* const newElement = ObjectTypes::createElementForXml (e, this))
|
||||
if (auto* newElement = ObjectTypes::createElementForXml (e, this))
|
||||
elements.add (newElement);
|
||||
|
||||
return true;
|
||||
|
|
@ -579,6 +566,12 @@ void PaintRoutine::fillInGeneratedCode (GeneratedCode& code, String& paintMethod
|
|||
if (! backgroundColour.isTransparent())
|
||||
paintMethodCode << "g.fillAll (" << CodeHelpers::colourToCode (backgroundColour) << ");\n\n";
|
||||
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
elements[i]->fillInGeneratedCode (code, paintMethodCode);
|
||||
for (auto* e : elements)
|
||||
e->fillInGeneratedCode (code, paintMethodCode);
|
||||
}
|
||||
|
||||
void PaintRoutine::applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
for (auto* e : elements)
|
||||
e->applyCustomPaintSnippets (snippets);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,8 @@ public:
|
|||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const;
|
||||
|
||||
void applyCustomPaintSnippets (StringArray&);
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
OwnedArray <PaintElement> elements;
|
||||
|
|
|
|||
|
|
@ -117,58 +117,89 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const
|
||||
String generateVariablesCode (String type) const
|
||||
{
|
||||
String s;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case solidColour:
|
||||
s << "g.setColour (" << CodeHelpers::colourToCode (colour) << ");\n";
|
||||
break;
|
||||
|
||||
case linearGradient:
|
||||
case radialGradient:
|
||||
{
|
||||
String x1, y1, w, h, x2, y2;
|
||||
positionToCode (gradPos1, code.document->getComponentLayout(), x1, y1, w, h);
|
||||
positionToCode (gradPos2, code.document->getComponentLayout(), x2, y2, w, h);
|
||||
|
||||
s << "g.setGradientFill (ColourGradient (";
|
||||
|
||||
const String indent (String::repeatedString (" ", s.length()));
|
||||
|
||||
s << CodeHelpers::colourToCode (gradCol1) << ",\n"
|
||||
<< indent << castToFloat (x1) << ", " << castToFloat (y1) << ",\n"
|
||||
<< indent << CodeHelpers::colourToCode (gradCol2) << ",\n"
|
||||
<< indent << castToFloat (x2) << ", " << castToFloat (y2) << ",\n"
|
||||
<< indent << CodeHelpers::boolLiteral (mode == radialGradient) << "));\n";
|
||||
case solidColour:
|
||||
s << "Colour " << type << "Colour = " << CodeHelpers::colourToCode (colour) << ";\n";
|
||||
break;
|
||||
}
|
||||
|
||||
case imageBrush:
|
||||
{
|
||||
const String imageVariable ("cachedImage_" + imageResourceName.replace ("::", "_") + "_" + String (code.getUniqueSuffix()));
|
||||
|
||||
code.addImageResourceLoader (imageVariable, imageResourceName);
|
||||
|
||||
String x, y, w, h;
|
||||
positionToCode (imageAnchor, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
s << "g.setTiledImageFill (";
|
||||
|
||||
const String indent (String::repeatedString (" ", s.length()));
|
||||
|
||||
s << imageVariable << ",\n"
|
||||
<< indent << x << ", " << y << ",\n"
|
||||
<< indent << CodeHelpers::floatLiteral (imageOpacity, 4) << ");\n";
|
||||
|
||||
case linearGradient:
|
||||
case radialGradient:
|
||||
s << "Colour " << type << "Colour1 = " << CodeHelpers::colourToCode (gradCol1) << ", " << type << "Colour2 = " << CodeHelpers::colourToCode (gradCol2) << ";\n";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
jassertfalse;
|
||||
break;
|
||||
case imageBrush:
|
||||
break;
|
||||
|
||||
default:
|
||||
jassertfalse;
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (String type, RelativePositionedRectangle relativeTo, GeneratedCode& code, String& paintMethodCode) const
|
||||
{
|
||||
String s;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case solidColour:
|
||||
s << "g.setColour (" << type << "Colour);\n";
|
||||
break;
|
||||
|
||||
case linearGradient:
|
||||
case radialGradient:
|
||||
{
|
||||
String x0, y0, x1, y1, w, h, x2, y2;
|
||||
positionToCode (relativeTo, code.document->getComponentLayout(), x0, y0, w, h);
|
||||
positionToCode (gradPos1, code.document->getComponentLayout(), x1, y1, w, h);
|
||||
positionToCode (gradPos2, code.document->getComponentLayout(), x2, y2, w, h);
|
||||
|
||||
s << "g.setGradientFill (ColourGradient (";
|
||||
|
||||
auto indent = String::repeatedString (" ", s.length());
|
||||
|
||||
s << type << "Colour1,\n"
|
||||
<< indent << castToFloat (x1) << " - " << castToFloat (x0) << " + x,\n"
|
||||
<< indent << castToFloat (y1) << " - " << castToFloat (y0) << " + y,\n"
|
||||
<< indent << type << "Colour2,\n"
|
||||
<< indent << castToFloat (x2) << " - " << castToFloat (x0) << " + x,\n"
|
||||
<< indent << castToFloat (y2) << " - " << castToFloat (y0) << " + y,\n"
|
||||
<< indent << CodeHelpers::boolLiteral (mode == radialGradient) << "));\n";
|
||||
break;
|
||||
}
|
||||
|
||||
case imageBrush:
|
||||
{
|
||||
auto imageVariable = "cachedImage_" + imageResourceName.replace ("::", "_") + "_" + String (code.getUniqueSuffix());
|
||||
|
||||
code.addImageResourceLoader (imageVariable, imageResourceName);
|
||||
|
||||
String x0, y0, x1, y1, w, h;
|
||||
positionToCode (relativeTo, code.document->getComponentLayout(), x0, y0, w, h);
|
||||
positionToCode (imageAnchor, code.document->getComponentLayout(), x1, y1, w, h);
|
||||
|
||||
s << "g.setTiledImageFill (";
|
||||
|
||||
const String indent (String::repeatedString (" ", s.length()));
|
||||
|
||||
s << imageVariable << ",\n"
|
||||
<< indent << x1 << " - " << x0 << " + x,\n"
|
||||
<< indent << y1 << " - " << y0 << " + y,\n"
|
||||
<< indent << CodeHelpers::floatLiteral (imageOpacity, 4) << ");\n";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
jassertfalse;
|
||||
break;
|
||||
}
|
||||
|
||||
paintMethodCode += s;
|
||||
|
|
@ -178,29 +209,29 @@ public:
|
|||
{
|
||||
switch (mode)
|
||||
{
|
||||
case solidColour:
|
||||
return "solid: " + colour.toString();
|
||||
case solidColour:
|
||||
return "solid: " + colour.toString();
|
||||
|
||||
case linearGradient:
|
||||
case radialGradient:
|
||||
return (mode == linearGradient ? "linear: "
|
||||
: " radial: ")
|
||||
+ gradPos1.toString()
|
||||
+ ", "
|
||||
+ gradPos2.toString()
|
||||
+ ", 0=" + gradCol1.toString()
|
||||
+ ", 1=" + gradCol2.toString();
|
||||
case linearGradient:
|
||||
case radialGradient:
|
||||
return (mode == linearGradient ? "linear: "
|
||||
: " radial: ")
|
||||
+ gradPos1.toString()
|
||||
+ ", "
|
||||
+ gradPos2.toString()
|
||||
+ ", 0=" + gradCol1.toString()
|
||||
+ ", 1=" + gradCol2.toString();
|
||||
|
||||
case imageBrush:
|
||||
return "image: " + imageResourceName.replaceCharacter (':', '#')
|
||||
+ ", "
|
||||
+ String (imageOpacity)
|
||||
+ ", "
|
||||
+ imageAnchor.toString();
|
||||
case imageBrush:
|
||||
return "image: " + imageResourceName.replaceCharacter (':', '#')
|
||||
+ ", "
|
||||
+ String (imageOpacity)
|
||||
+ ", "
|
||||
+ imageAnchor.toString();
|
||||
|
||||
default:
|
||||
jassertfalse;
|
||||
break;
|
||||
default:
|
||||
jassertfalse;
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ public:
|
|||
void changeListenerCallback (ChangeBroadcaster*);
|
||||
void parentHierarchyChanged();
|
||||
|
||||
virtual void applyCustomPaintSnippets (StringArray&) {}
|
||||
|
||||
int borderThickness;
|
||||
|
||||
protected:
|
||||
|
|
@ -159,7 +161,7 @@ public:
|
|||
void changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
jassert (propToRefresh != nullptr);
|
||||
if (propToRefresh != nullptr)
|
||||
if (propToRefresh != nullptr && owner != nullptr)
|
||||
propToRefresh->refresh();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,35 +62,53 @@ public:
|
|||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode)
|
||||
{
|
||||
if (fillType.isInvisible() && (strokeType.isInvisible() || ! isStrokePresent))
|
||||
return;
|
||||
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
s << "{\n"
|
||||
<< " float x = " << castToFloat (x) << ", y = " << castToFloat (y) << ", "
|
||||
<< "width = " << castToFloat (w) << ", height = " << castToFloat (h) << ";\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
s << " " << fillType.generateVariablesCode ("fill");
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
s << " " << strokeType.fill.generateVariablesCode ("stroke");
|
||||
|
||||
s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
fillType.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.fillEllipse ("
|
||||
<< castToFloat (x) << ", "
|
||||
<< castToFloat (y) << ", "
|
||||
<< castToFloat (w) << ", "
|
||||
<< castToFloat (h) << ");\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
s << " ";
|
||||
fillType.fillInGeneratedCode ("fill", position, code, s);
|
||||
s << " g.fillEllipse (x, y, width, height);\n";
|
||||
}
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
s << " ";
|
||||
strokeType.fill.fillInGeneratedCode ("stroke", position, code, s);
|
||||
s << " g.drawEllipse (x, y, width, height, " << CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n";
|
||||
}
|
||||
|
||||
strokeType.fill.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.drawEllipse ("
|
||||
<< castToFloat (x) << ", "
|
||||
<< castToFloat (y) << ", "
|
||||
<< castToFloat (w) << ", "
|
||||
<< castToFloat (h) << ", "
|
||||
<< CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n\n";
|
||||
s << "}\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
paintMethodCode += s;
|
||||
}
|
||||
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,10 +149,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
String customPaintCode;
|
||||
|
||||
//==============================================================================
|
||||
class ShapeToPathProperty : public ButtonPropertyComponent
|
||||
struct ShapeToPathProperty : public ButtonPropertyComponent
|
||||
{
|
||||
public:
|
||||
ShapeToPathProperty (PaintElementEllipse* const e)
|
||||
: ButtonPropertyComponent ("path", false),
|
||||
element (e)
|
||||
|
|
@ -151,7 +170,6 @@ private:
|
|||
return "convert to a path";
|
||||
}
|
||||
|
||||
private:
|
||||
PaintElementEllipse* const element;
|
||||
PaintElementEllipse* element;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -209,12 +209,17 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
OwnedArray <PaintElement> subElements;
|
||||
|
||||
class UngroupProperty : public ButtonPropertyComponent
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
for (auto* e : subElements)
|
||||
e->applyCustomPaintSnippets (snippets);
|
||||
}
|
||||
|
||||
private:
|
||||
OwnedArray<PaintElement> subElements;
|
||||
|
||||
struct UngroupProperty : public ButtonPropertyComponent
|
||||
{
|
||||
public:
|
||||
UngroupProperty (PaintElementGroup* const e)
|
||||
: ButtonPropertyComponent ("ungroup", false),
|
||||
element (e)
|
||||
|
|
@ -231,7 +236,6 @@ private:
|
|||
return "Ungroup";
|
||||
}
|
||||
|
||||
private:
|
||||
PaintElementGroup* const element;
|
||||
PaintElementGroup* element;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -95,10 +95,16 @@ public:
|
|||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode)
|
||||
{
|
||||
String r;
|
||||
|
||||
if (opacity > 0)
|
||||
{
|
||||
String x, y, w, h, r;
|
||||
positionToCode (position, getDocument()->getComponentLayout(), x, y, w, h);
|
||||
r << "{\n"
|
||||
<< " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n"
|
||||
<< " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n";
|
||||
|
||||
if (dynamic_cast<const DrawableImage*> (getDrawable()) != 0)
|
||||
{
|
||||
const String imageVariable ("cachedImage_" + resourceName.replace ("::", "_") + "_" + String (code.getUniqueSuffix()));
|
||||
|
|
@ -106,36 +112,32 @@ public:
|
|||
code.addImageResourceLoader (imageVariable, resourceName);
|
||||
|
||||
if (opacity >= 254.0 / 255.0)
|
||||
r << "g.setColour (Colours::black);\n";
|
||||
r << " g.setColour (Colours::black);\n";
|
||||
else
|
||||
r << "g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n";
|
||||
r << " g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n";
|
||||
|
||||
String x, y, w, h;
|
||||
positionToCode (position, getDocument()->getComponentLayout(), x, y, w, h);
|
||||
|
||||
if (mode == stretched)
|
||||
{
|
||||
r << "g.drawImage (" << imageVariable << ",\n "
|
||||
<< x << ", " << y << ", " << w << ", " << h
|
||||
<< ",\n 0, 0, "
|
||||
<< imageVariable << ".getWidth(), "
|
||||
<< imageVariable << ".getHeight());\n\n";
|
||||
r << " g.drawImage (" << imageVariable << ",\n"
|
||||
<< " x, y, width, height,\n"
|
||||
<< " 0, 0, " << imageVariable << ".getWidth(), " << imageVariable << ".getHeight());\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
r << "g.drawImageWithin (" << imageVariable << ",\n "
|
||||
<< x << ", " << y << ", " << w << ", " << h
|
||||
<< ",\n ";
|
||||
r << " g.drawImageWithin (" << imageVariable << ",\n"
|
||||
<< " x, y, width, height,\n"
|
||||
<< " ";
|
||||
|
||||
if (mode == proportionalReducingOnly)
|
||||
r << "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize";
|
||||
else
|
||||
r << "RectanglePlacement::centred";
|
||||
|
||||
r << ",\n false);\n\n";
|
||||
r << ",\n"
|
||||
<< " false);\n";
|
||||
}
|
||||
|
||||
paintMethodCode += r;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -154,28 +156,35 @@ public:
|
|||
<< imageVariable << " = nullptr;\n";
|
||||
|
||||
if (opacity >= 254.0 / 255.0)
|
||||
r << "g.setColour (Colours::black);\n";
|
||||
r << " g.setColour (Colours::black);\n";
|
||||
else
|
||||
r << "g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n";
|
||||
r << " g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n";
|
||||
|
||||
String x, y, w, h;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
r << "jassert (" << imageVariable << " != 0);\n"
|
||||
<< "if (" << imageVariable << " != 0)\n "
|
||||
<< imageVariable << "->drawWithin (g, Rectangle<float> ("
|
||||
<< x << ", " << y << ", " << w << ", " << h
|
||||
<< "),\n"
|
||||
<< String::repeatedString (" ", imageVariable.length() + 18)
|
||||
r << " jassert (" << imageVariable << " != 0);\n"
|
||||
<< " if (" << imageVariable << " != 0)\n"
|
||||
<< " " << imageVariable << "->drawWithin (g, Rectangle<float> (x, y, width, height),\n"
|
||||
<< " " << String::repeatedString (" ", imageVariable.length() + 18)
|
||||
<< (mode == stretched ? "RectanglePlacement::stretchToFit"
|
||||
: (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize"
|
||||
: "RectanglePlacement::centred"))
|
||||
<< ", " << CodeHelpers::floatLiteral (opacity, 3)
|
||||
<< ");\n\n";
|
||||
|
||||
paintMethodCode += r;
|
||||
<< ", " << CodeHelpers::floatLiteral (opacity, 3) << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
r << "}\n\n";
|
||||
|
||||
paintMethodCode += r;
|
||||
}
|
||||
}
|
||||
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && opacity > 0)
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,6 +394,7 @@ private:
|
|||
String resourceName;
|
||||
double opacity;
|
||||
StretchMode mode;
|
||||
String customPaintCode;
|
||||
|
||||
//==============================================================================
|
||||
class ImageElementResourceProperty : public ImageResourceProperty <PaintElementImage>
|
||||
|
|
|
|||
|
|
@ -382,10 +382,8 @@ void PaintElementPath::fillInGeneratedCode (GeneratedCode& code, String& paintMe
|
|||
if (! nonZeroWinding)
|
||||
r << pathVariable << ".setUsingNonZeroWinding (false);\n";
|
||||
|
||||
for (int i = 0; i < points.size(); ++i)
|
||||
for (auto* p : points)
|
||||
{
|
||||
const PathPoint* const p = points.getUnchecked(i);
|
||||
|
||||
switch (p->type)
|
||||
{
|
||||
case Path::Iterator::startNewSubPath:
|
||||
|
|
@ -400,15 +398,17 @@ void PaintElementPath::fillInGeneratedCode (GeneratedCode& code, String& paintMe
|
|||
|
||||
case Path::Iterator::quadraticTo:
|
||||
r << pathVariable << ".quadraticTo (" << positionToPairOfValues (p->pos[0], layout)
|
||||
<< ", " << positionToPairOfValues (p->pos[1], layout) << ");\n";
|
||||
<< ", " << positionToPairOfValues (p->pos[1], layout) << ");\n";
|
||||
|
||||
somePointsAreRelative = somePointsAreRelative || ! p->pos[0].rect.isPositionAbsolute();
|
||||
somePointsAreRelative = somePointsAreRelative || ! p->pos[1].rect.isPositionAbsolute();
|
||||
break;
|
||||
|
||||
case Path::Iterator::cubicTo:
|
||||
r << pathVariable << ".cubicTo (" << positionToPairOfValues (p->pos[0], layout)
|
||||
<< ", " << positionToPairOfValues (p->pos[1], layout)
|
||||
<< ", " << positionToPairOfValues (p->pos[2], layout) << ");\n";
|
||||
<< ", " << positionToPairOfValues (p->pos[1], layout)
|
||||
<< ", " << positionToPairOfValues (p->pos[2], layout) << ");\n";
|
||||
|
||||
somePointsAreRelative = somePointsAreRelative || ! p->pos[0].rect.isPositionAbsolute();
|
||||
somePointsAreRelative = somePointsAreRelative || ! p->pos[1].rect.isPositionAbsolute();
|
||||
somePointsAreRelative = somePointsAreRelative || ! p->pos[2].rect.isPositionAbsolute();
|
||||
|
|
@ -432,24 +432,50 @@ void PaintElementPath::fillInGeneratedCode (GeneratedCode& code, String& paintMe
|
|||
else
|
||||
code.constructorCode << r;
|
||||
|
||||
String s;
|
||||
s << "{\n"
|
||||
<< " float x = 0, y = 0;\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
s << " " << fillType.generateVariablesCode ("fill");
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
s << " " << strokeType.fill.generateVariablesCode ("stroke");
|
||||
|
||||
s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n";
|
||||
|
||||
RelativePositionedRectangle zero;
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
{
|
||||
fillType.fillInGeneratedCode (code, paintMethodCode);
|
||||
|
||||
paintMethodCode << "g.fillPath (" << pathVariable << ");\n";
|
||||
s << " ";
|
||||
fillType.fillInGeneratedCode ("fill", zero, code, s);
|
||||
s << " g.fillPath (" << pathVariable << ", AffineTransform::translation(x, y));\n";
|
||||
}
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
{
|
||||
String s;
|
||||
|
||||
strokeType.fill.fillInGeneratedCode (code, s);
|
||||
s << "g.strokePath (" << pathVariable << ", " << strokeType.getPathStrokeCode() << ");\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
s << " ";
|
||||
strokeType.fill.fillInGeneratedCode ("stroke", zero, code, s);
|
||||
s << " g.strokePath (" << pathVariable << ", " << strokeType.getPathStrokeCode() << ", AffineTransform::translation(x, y));\n";
|
||||
}
|
||||
|
||||
paintMethodCode += "\n";
|
||||
s << "}\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
}
|
||||
|
||||
void PaintElementPath::applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
void getEditableProperties (Array<PropertyComponent*>& props);
|
||||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode);
|
||||
void applyCustomPaintSnippets (StringArray& snippets);
|
||||
|
||||
//==============================================================================
|
||||
static const char* getTagName() noexcept { return "PATH"; }
|
||||
|
|
@ -132,6 +133,7 @@ private:
|
|||
mutable Rectangle<int> lastPathBounds;
|
||||
int mouseDownOnSegment;
|
||||
bool mouseDownSelectSegmentStatus;
|
||||
String customPaintCode;
|
||||
|
||||
String pathToString() const;
|
||||
void restorePathFromString (const String& s);
|
||||
|
|
|
|||
|
|
@ -76,27 +76,52 @@ public:
|
|||
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode)
|
||||
{
|
||||
if (fillType.isInvisible() && (strokeType.isInvisible() || ! isStrokePresent))
|
||||
return;
|
||||
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
s << "{\n"
|
||||
<< " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
s << " " << fillType.generateVariablesCode ("fill");
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
s << " " << strokeType.fill.generateVariablesCode ("stroke");
|
||||
|
||||
s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
fillType.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.fillRect (" << x << ", " << y << ", " << w << ", " << h << ");\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
s << " ";
|
||||
fillType.fillInGeneratedCode ("fill", position, code, s);
|
||||
s << " g.fillRect (x, y, width, height);\n";
|
||||
}
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
s << " ";
|
||||
strokeType.fill.fillInGeneratedCode ("stroke", position, code, s);
|
||||
s << " g.drawRect (x, y, width, height, " << roundToInt (strokeType.stroke.getStrokeThickness()) << ");\n\n";
|
||||
}
|
||||
|
||||
strokeType.fill.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.drawRect (" << x << ", " << y << ", " << w << ", " << h << ", "
|
||||
<< roundToInt (strokeType.stroke.getStrokeThickness()) << ");\n\n";
|
||||
s << "}\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
paintMethodCode += s;
|
||||
}
|
||||
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -134,6 +159,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
String customPaintCode;
|
||||
|
||||
class ShapeToPathProperty : public ButtonPropertyComponent
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -116,37 +116,54 @@ public:
|
|||
//==============================================================================
|
||||
void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode)
|
||||
{
|
||||
if (fillType.isInvisible() && (strokeType.isInvisible() || ! isStrokePresent))
|
||||
return;
|
||||
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
s << "{\n"
|
||||
<< " float x = " << castToFloat (x) << ", y = " << castToFloat (y) << ", "
|
||||
<< "width = " << castToFloat (w) << ", height = " << castToFloat (h) << ";\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
s << " " << fillType.generateVariablesCode ("fill");
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
s << " " << strokeType.fill.generateVariablesCode ("stroke");
|
||||
|
||||
s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n";
|
||||
|
||||
if (! fillType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
fillType.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.fillRoundedRectangle ("
|
||||
<< castToFloat (x) << ", "
|
||||
<< castToFloat (y) << ", "
|
||||
<< castToFloat (w) << ", "
|
||||
<< castToFloat (h) << ", "
|
||||
<< CodeHelpers::floatLiteral (cornerSize, 3) << ");\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
s << " ";
|
||||
fillType.fillInGeneratedCode ("fill", position, code, s);
|
||||
s << " g.fillRoundedRectangle (x, y, width, height, " << CodeHelpers::floatLiteral (cornerSize, 3) << ");\n";
|
||||
}
|
||||
|
||||
if (isStrokePresent && ! strokeType.isInvisible())
|
||||
{
|
||||
String x, y, w, h, s;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
s << " ";
|
||||
strokeType.fill.fillInGeneratedCode ("stroke", position, code, s);
|
||||
s << " g.drawRoundedRectangle (x, y, width, height, " << CodeHelpers::floatLiteral (cornerSize, 3)
|
||||
<< ", " << CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n";
|
||||
}
|
||||
|
||||
strokeType.fill.fillInGeneratedCode (code, paintMethodCode);
|
||||
s << "g.drawRoundedRectangle ("
|
||||
<< castToFloat (x) << ", "
|
||||
<< castToFloat (y) << ", "
|
||||
<< castToFloat (w) << ", "
|
||||
<< castToFloat (h) << ", "
|
||||
<< CodeHelpers::floatLiteral (cornerSize, 3) << ", "
|
||||
<< CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n\n";
|
||||
s << "}\n\n";
|
||||
|
||||
paintMethodCode += s;
|
||||
paintMethodCode += s;
|
||||
}
|
||||
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +208,7 @@ public:
|
|||
|
||||
private:
|
||||
double cornerSize;
|
||||
String customPaintCode;
|
||||
|
||||
//==============================================================================
|
||||
class CornerSizeProperty : public SliderPropertyComponent,
|
||||
|
|
|
|||
|
|
@ -83,27 +83,37 @@ public:
|
|||
{
|
||||
if (! fillType.isInvisible())
|
||||
{
|
||||
String r;
|
||||
|
||||
fillType.fillInGeneratedCode (code, paintMethodCode);
|
||||
|
||||
String x, y, w, h;
|
||||
String x, y, w, h, r;
|
||||
positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
r << "g.setFont ("
|
||||
<< FontPropertyComponent::getCompleteFontCode (font, typefaceName)
|
||||
<< ");\ng.drawText ("
|
||||
<< quotedString (text, code.shouldUseTransMacro())
|
||||
<< ",\n "
|
||||
<< x << ", " << y << ", " << w << ", " << h
|
||||
<< ",\n "
|
||||
<< CodeHelpers::justificationToCode (justification)
|
||||
<< ", true);\n\n";
|
||||
|
||||
r << "{\n"
|
||||
<< " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n"
|
||||
<< " String text (" << quotedString (text, code.shouldUseTransMacro()) << ");\n"
|
||||
<< " " << fillType.generateVariablesCode ("fill")
|
||||
<< " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
|
||||
<< customPaintCode
|
||||
<< " //[/UserPaintCustomArguments]\n"
|
||||
<< " ";
|
||||
fillType.fillInGeneratedCode ("fill", position, code, r);
|
||||
r << " g.setFont (" << FontPropertyComponent::getCompleteFontCode (font, typefaceName) << ");\n"
|
||||
<< " g.drawText (text, x, y, width, height,\n"
|
||||
<< " " << CodeHelpers::justificationToCode (justification) << ", true);\n"
|
||||
<< "}\n\n";
|
||||
|
||||
paintMethodCode += r;
|
||||
}
|
||||
}
|
||||
|
||||
void applyCustomPaintSnippets (StringArray& snippets)
|
||||
{
|
||||
customPaintCode.clear();
|
||||
|
||||
if (! snippets.isEmpty() && ! fillType.isInvisible())
|
||||
{
|
||||
customPaintCode = snippets[0];
|
||||
snippets.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* getTagName() noexcept { return "TEXT"; }
|
||||
|
||||
XmlElement* createXml() const
|
||||
|
|
@ -376,7 +386,8 @@ private:
|
|||
Font font;
|
||||
String typefaceName;
|
||||
Justification justification;
|
||||
|
||||
String customPaintCode;
|
||||
|
||||
Array <Justification> justificationTypes;
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -318,11 +318,7 @@ static SourceCodeEditor* createCodeEditor (const File& file, SourceCodeDocument&
|
|||
//==============================================================================
|
||||
JucerDocumentEditor::JucerDocumentEditor (JucerDocument* const doc)
|
||||
: document (doc),
|
||||
tabbedComponent (TabbedButtonBar::TabsAtTop),
|
||||
compLayoutPanel (0),
|
||||
lastViewportX (0),
|
||||
lastViewportY (0),
|
||||
currentZoomLevel (1.0)
|
||||
tabbedComponent (doc)
|
||||
{
|
||||
setOpaque (true);
|
||||
|
||||
|
|
@ -1028,9 +1024,7 @@ bool JucerDocumentEditor::perform (const InvocationInfo& info)
|
|||
|
||||
case StandardApplicationCommandIDs::paste:
|
||||
{
|
||||
ScopedPointer<XmlElement> doc (XmlDocument::parse (SystemClipboard::getTextFromClipboard()));
|
||||
|
||||
if (doc != nullptr)
|
||||
if (ScopedPointer<XmlElement> doc = XmlDocument::parse (SystemClipboard::getTextFromClipboard()))
|
||||
{
|
||||
if (doc->hasTagName (ComponentLayout::clipboardXmlTag))
|
||||
{
|
||||
|
|
@ -1095,9 +1089,8 @@ bool JucerDocumentEditor::keyPressed (const KeyPress& key)
|
|||
JucerDocumentEditor* JucerDocumentEditor::getActiveDocumentHolder()
|
||||
{
|
||||
ApplicationCommandInfo info (0);
|
||||
ApplicationCommandTarget* target = ProjucerApplication::getCommandManager().getTargetForCommand (JucerCommandIDs::editCompLayout, info);
|
||||
|
||||
return dynamic_cast<JucerDocumentEditor*> (target);
|
||||
return dynamic_cast<JucerDocumentEditor*> (ProjucerApplication::getCommandManager()
|
||||
.getTargetForCommand (JucerCommandIDs::editCompLayout, info));
|
||||
}
|
||||
|
||||
Image JucerDocumentEditor::createComponentLayerSnapshot() const
|
||||
|
|
@ -1105,7 +1098,7 @@ Image JucerDocumentEditor::createComponentLayerSnapshot() const
|
|||
if (compLayoutPanel != nullptr)
|
||||
return compLayoutPanel->createComponentSnapshot();
|
||||
|
||||
return Image();
|
||||
return {};
|
||||
}
|
||||
|
||||
const int gridSnapMenuItemBase = 0x8723620;
|
||||
|
|
@ -1187,13 +1180,13 @@ void createGUIEditorMenu (PopupMenu& menu)
|
|||
|
||||
void handleGUIEditorMenuCommand (int menuItemID)
|
||||
{
|
||||
if (JucerDocumentEditor* ed = JucerDocumentEditor::getActiveDocumentHolder())
|
||||
if (auto* ed = JucerDocumentEditor::getActiveDocumentHolder())
|
||||
{
|
||||
int gridIndex = menuItemID - gridSnapMenuItemBase;
|
||||
|
||||
if (isPositiveAndBelow (gridIndex, numElementsInArray (snapSizes)))
|
||||
{
|
||||
JucerDocument& doc = *ed->getDocument();
|
||||
auto& doc = *ed->getDocument();
|
||||
|
||||
doc.setSnappingGrid (snapSizes [gridIndex],
|
||||
doc.isSnapActive (false),
|
||||
|
|
|
|||
|
|
@ -58,28 +58,37 @@ public:
|
|||
Image createComponentLayerSnapshot() const;
|
||||
|
||||
//==============================================================================
|
||||
void paint (Graphics& g);
|
||||
void resized();
|
||||
void changeListenerCallback (ChangeBroadcaster*);
|
||||
bool keyPressed (const KeyPress&);
|
||||
void paint (Graphics& g) override;
|
||||
void resized() override;
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
bool keyPressed (const KeyPress&) override;
|
||||
|
||||
//==============================================================================
|
||||
ApplicationCommandTarget* getNextCommandTarget();
|
||||
void getAllCommands (Array <CommandID>&);
|
||||
void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result);
|
||||
bool perform (const InvocationInfo&);
|
||||
ApplicationCommandTarget* getNextCommandTarget() override;
|
||||
void getAllCommands (Array<CommandID>&) override;
|
||||
void getCommandInfo (CommandID, ApplicationCommandInfo&) override;
|
||||
bool perform (const InvocationInfo&) override;
|
||||
|
||||
static JucerDocumentEditor* getActiveDocumentHolder();
|
||||
|
||||
private:
|
||||
ScopedPointer<JucerDocument> document;
|
||||
TabbedComponent tabbedComponent;
|
||||
ComponentLayoutPanel* compLayoutPanel;
|
||||
ComponentLayoutPanel* compLayoutPanel = nullptr;
|
||||
|
||||
struct JucerDocumentTabs : public TabbedComponent
|
||||
{
|
||||
JucerDocumentTabs (JucerDocument* d) : TabbedComponent (TabbedButtonBar::TabsAtTop), document (d) {}
|
||||
void currentTabChanged (int, const String&) override { document->refreshCustomCodeFromDocument(); }
|
||||
|
||||
JucerDocument* document;
|
||||
};
|
||||
|
||||
JucerDocumentTabs tabbedComponent;
|
||||
|
||||
int lastViewportX = 0, lastViewportY = 0;
|
||||
double currentZoomLevel = 1.0;
|
||||
|
||||
bool isSomethingSelected() const;
|
||||
int lastViewportX, lastViewportY;
|
||||
|
||||
double currentZoomLevel;
|
||||
|
||||
// only non-zero if a layout tab is selected
|
||||
ComponentLayout* getCurrentLayout() const;
|
||||
|
|
@ -89,6 +98,6 @@ private:
|
|||
void setZoom (double scale);
|
||||
double getZoom() const;
|
||||
|
||||
void addElement (const int index);
|
||||
void addComponent (const int index);
|
||||
void addElement (int index);
|
||||
void addComponent (int index);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,23 +36,39 @@ namespace CodeHelpers
|
|||
if (numSpaces == 0)
|
||||
return code;
|
||||
|
||||
const String space (String::repeatedString (" ", numSpaces));
|
||||
auto space = String::repeatedString (" ", numSpaces);
|
||||
auto lines = StringArray::fromLines (code);
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (code);
|
||||
|
||||
for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i)
|
||||
for (auto& line : lines)
|
||||
{
|
||||
String s (lines[i].trimEnd());
|
||||
if (s.isNotEmpty())
|
||||
s = space + s;
|
||||
if (! indentFirstLine)
|
||||
{
|
||||
indentFirstLine = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.set (i, s);
|
||||
if (line.trimEnd().isNotEmpty())
|
||||
line = space + line;
|
||||
}
|
||||
|
||||
return lines.joinIntoString (newLine);
|
||||
}
|
||||
|
||||
String unindent (const String& code, const int numSpaces)
|
||||
{
|
||||
if (numSpaces == 0)
|
||||
return code;
|
||||
|
||||
auto space = String::repeatedString (" ", numSpaces);
|
||||
auto lines = StringArray::fromLines (code);
|
||||
|
||||
for (auto& line : lines)
|
||||
if (line.startsWith (space))
|
||||
line = line.substring (numSpaces);
|
||||
|
||||
return lines.joinIntoString (newLine);
|
||||
}
|
||||
|
||||
String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
//==============================================================================
|
||||
namespace CodeHelpers
|
||||
{
|
||||
String indent (const String& code, const int numSpaces, bool indentFirstLine);
|
||||
String indent (const String& code, int numSpaces, bool indentFirstLine);
|
||||
String unindent (const String& code, int numSpaces);
|
||||
String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates);
|
||||
String createIncludeStatement (const File& includedFile, const File& targetFile);
|
||||
String createIncludeStatement (const String& includePath);
|
||||
|
|
@ -41,7 +42,7 @@ namespace CodeHelpers
|
|||
String floatLiteral (double value, int numDecPlaces);
|
||||
String boolLiteral (bool value);
|
||||
|
||||
String colourToCode (Colour col);
|
||||
String colourToCode (Colour);
|
||||
String justificationToCode (Justification);
|
||||
|
||||
String alignFunctionCallParams (const String& call, const StringArray& parameters, int maxLineLength);
|
||||
|
|
@ -50,7 +51,7 @@ namespace CodeHelpers
|
|||
bool breakAtNewLines, bool allowStringBreaks);
|
||||
|
||||
void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
|
||||
const StringArray& strings, const StringArray& codeToExecute, const int indentLevel);
|
||||
const StringArray& strings, const StringArray& codeToExecute, int indentLevel);
|
||||
|
||||
String getLeadingWhitespace (String line);
|
||||
int getBraceCount (String::CharPointerType line);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue