| @@ -29,13 +29,13 @@ | |||
| //============================================================================== | |||
| class SVGPathDataComponent : public Component, | |||
| private TextEditor::Listener | |||
| public FileDragAndDropTarget, | |||
| private TextEditor::Listener, | |||
| private Button::Listener | |||
| { | |||
| public: | |||
| SVGPathDataComponent() | |||
| : desc (String(), | |||
| "Paste an SVG path string into the top box, and it'll be converted to some C++ " | |||
| "code that will load it as a Path object..") | |||
| { | |||
| desc.setJustificationType (Justification::centred); | |||
| addAndMakeVisible (desc); | |||
| @@ -53,6 +53,15 @@ public: | |||
| addAndMakeVisible (resultText); | |||
| userText.setText (getLastText()); | |||
| addAndMakeVisible (copyButton); | |||
| copyButton.addListener (this); | |||
| } | |||
| void buttonClicked (Button* b) override | |||
| { | |||
| if (b == ©Button) | |||
| SystemClipboard::copyTextToClipboard (resultText.getText()); | |||
| } | |||
| void textEditorTextChanged (TextEditor&) override | |||
| @@ -68,8 +77,12 @@ public: | |||
| void update() | |||
| { | |||
| getLastText() = userText.getText(); | |||
| auto text = getLastText().trim().unquoted().trim(); | |||
| path = Drawable::parseSVGPath (getLastText().trim().unquoted().trim()); | |||
| path = Drawable::parseSVGPath (text); | |||
| if (path.isEmpty()) | |||
| path = pathFromPoints (text); | |||
| String result = "No path generated.. Not a valid SVG path string?"; | |||
| @@ -96,7 +109,10 @@ public: | |||
| void resized() override | |||
| { | |||
| Rectangle<int> r (getLocalBounds().reduced (8)); | |||
| auto r = getLocalBounds().reduced (8); | |||
| copyButton.setBounds (r.removeFromBottom (30).removeFromLeft (50)); | |||
| r.removeFromBottom (5); | |||
| desc.setBounds (r.removeFromTop (44)); | |||
| r.removeFromTop (8); | |||
| userText.setBounds (r.removeFromTop (r.getHeight() / 2)); | |||
| @@ -107,7 +123,11 @@ public: | |||
| void paint (Graphics& g) override | |||
| { | |||
| g.setColour (findColour (secondaryBackgroundColourId)); | |||
| if (dragOver) | |||
| { | |||
| g.setColour (findColour (secondaryBackgroundColourId).brighter()); | |||
| g.fillAll(); | |||
| } | |||
| g.setColour (findColour (defaultTextColourId)); | |||
| g.fillPath (path, path.getTransformToScaleToFit (previewPathArea.reduced (4).toFloat(), true)); | |||
| @@ -119,11 +139,72 @@ public: | |||
| resultText.applyFontToAllText (resultText.getFont()); | |||
| } | |||
| bool isInterestedInFileDrag (const StringArray& files) override | |||
| { | |||
| return files.size() == 1 | |||
| && File (files[0]).hasFileExtension ("svg"); | |||
| } | |||
| void fileDragEnter (const StringArray&, int, int) override | |||
| { | |||
| dragOver = true; | |||
| repaint(); | |||
| } | |||
| void fileDragExit (const StringArray&) override | |||
| { | |||
| dragOver = false; | |||
| repaint(); | |||
| } | |||
| void filesDropped (const StringArray& files, int, int) override | |||
| { | |||
| dragOver = false; | |||
| repaint(); | |||
| if (ScopedPointer<XmlElement> e = XmlDocument::parse (File (files[0]))) | |||
| { | |||
| if (auto* ePath = e->getChildByName ("path")) | |||
| userText.setText (ePath->getStringAttribute ("d"), true); | |||
| else if (auto* ePolygon = e->getChildByName ("polygon")) | |||
| userText.setText (ePolygon->getStringAttribute ("points"), true); | |||
| } | |||
| } | |||
| Path pathFromPoints (String pointsText) | |||
| { | |||
| auto points = StringArray::fromTokens (pointsText, " ,", ""); | |||
| points.removeEmptyStrings(); | |||
| jassert (points.size() % 2 == 0); | |||
| Path p; | |||
| for (int i = 0; i < points.size() / 2; i++) | |||
| { | |||
| auto x = points[i * 2].getFloatValue(); | |||
| auto y = points[i * 2 + 1].getFloatValue(); | |||
| if (i == 0) | |||
| p.startNewSubPath ({ x, y }); | |||
| else | |||
| p.lineTo ({ x, y }); | |||
| } | |||
| p.closeSubPath(); | |||
| return p; | |||
| } | |||
| private: | |||
| Label desc; | |||
| Label desc { {}, "Paste an SVG path string into the top box, and it'll be converted to some C++ " | |||
| "code that will load it as a Path object.." }; | |||
| TextButton copyButton { "Copy" }; | |||
| TextEditor userText, resultText; | |||
| Rectangle<int> previewPathArea; | |||
| Path path; | |||
| bool dragOver = false; | |||
| String& getLastText() | |||
| { | |||