migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

View File

@ -1,430 +1,430 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../Application/jucer_Application.h"
#include "jucer_ComponentLayoutEditor.h"
#include "../UI/jucer_JucerCommandIDs.h"
#include "../jucer_ObjectTypes.h"
#include "../Components/jucer_JucerComponentHandler.h"
//==============================================================================
class SubComponentHolderComp : public Component
{
public:
SubComponentHolderComp (JucerDocument& doc,
SnapGridPainter& g)
: document (doc), grid (g),
dontFillBackground (false)
{
setInterceptsMouseClicks (false, false);
setWantsKeyboardFocus (false);
setFocusContainerType (FocusContainerType::keyboardFocusContainer);
}
void paint (Graphics& g) override
{
if (! dontFillBackground)
{
if (PaintRoutine* const background = document.getPaintRoutine (0))
{
background->fillWithBackground (g, false);
background->drawElements (g, getLocalBounds());
grid.draw (g, background);
}
else
{
grid.draw (g, nullptr);
}
}
}
void resized() override
{
if (! getBounds().isEmpty())
{
int numTimesToTry = 10;
while (--numTimesToTry >= 0)
{
bool anyCompsMoved = false;
for (int i = 0; i < getNumChildComponents(); ++i)
{
Component* comp = getChildComponent (i);
if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp))
{
const Rectangle<int> newBounds (type->getComponentPosition (comp)
.getRectangle (getLocalBounds(),
document.getComponentLayout()));
anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds);
comp->setBounds (newBounds);
}
}
// repeat this loop until they've all stopped shuffling (might require a few
// loops for all the relative positioned comps to settle down)
if (! anyCompsMoved)
break;
}
}
}
void moved() override
{
((ComponentLayoutEditor*) getParentComponent())->updateOverlayPositions();
}
JucerDocument& document;
SnapGridPainter& grid;
bool dontFillBackground;
};
//==============================================================================
ComponentLayoutEditor::ComponentLayoutEditor (JucerDocument& doc, ComponentLayout& cl)
: document (doc), layout (cl), firstResize (true)
{
setWantsKeyboardFocus (true);
addAndMakeVisible (subCompHolder = new SubComponentHolderComp (document, grid));
refreshAllComponents();
setSize (document.getInitialWidth(),
document.getInitialHeight());
}
ComponentLayoutEditor::~ComponentLayoutEditor()
{
document.removeChangeListener (this);
removeChildComponent (&lassoComp);
deleteAllChildren();
}
//==============================================================================
void ComponentLayoutEditor::visibilityChanged()
{
document.beginTransaction();
if (isVisible())
{
refreshAllComponents();
document.addChangeListener (this);
}
else
{
document.removeChangeListener (this);
}
}
void ComponentLayoutEditor::changeListenerCallback (ChangeBroadcaster*)
{
refreshAllComponents();
}
void ComponentLayoutEditor::paint (Graphics&)
{
}
void ComponentLayoutEditor::resized()
{
if (firstResize && getWidth() > 0 && getHeight() > 0)
{
firstResize = false;
refreshAllComponents();
}
subCompHolder->setBounds (getComponentArea());
updateOverlayPositions();
}
Rectangle<int> ComponentLayoutEditor::getComponentArea() const
{
const int editorEdgeGap = 4;
if (document.isFixedSize())
return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2,
(getHeight() - document.getInitialHeight()) / 2,
document.getInitialWidth(),
document.getInitialHeight());
return Rectangle<int> (editorEdgeGap, editorEdgeGap,
getWidth() - editorEdgeGap * 2,
getHeight() - editorEdgeGap * 2);
}
Image ComponentLayoutEditor::createComponentLayerSnapshot() const
{
((SubComponentHolderComp*) subCompHolder)->dontFillBackground = true;
Image im = subCompHolder->createComponentSnapshot (Rectangle<int> (0, 0, subCompHolder->getWidth(), subCompHolder->getHeight()));
((SubComponentHolderComp*) subCompHolder)->dontFillBackground = false;
return im;
}
void ComponentLayoutEditor::updateOverlayPositions()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (ComponentOverlayComponent* const overlay = dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)))
overlay->updateBoundsToMatchTarget();
}
void ComponentLayoutEditor::refreshAllComponents()
{
for (int i = getNumChildComponents(); --i >= 0;)
{
std::unique_ptr<ComponentOverlayComponent> overlay (dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)));
if (overlay != nullptr && layout.containsComponent (overlay->target))
overlay.release();
}
for (int i = subCompHolder->getNumChildComponents(); --i >= 0;)
{
Component* const comp = subCompHolder->getChildComponent (i);
if (! layout.containsComponent (comp))
subCompHolder->removeChildComponent (comp);
}
Component* lastComp = nullptr;
Component* lastOverlay = nullptr;
for (int i = layout.getNumComponents(); --i >= 0;)
{
auto c = layout.getComponent (i);
jassert (c != nullptr);
auto overlay = getOverlayCompFor (c);
bool isNewOverlay = false;
if (overlay == nullptr)
{
auto handler = ComponentTypeHandler::getHandlerFor (*c);
jassert (handler != nullptr);
overlay = handler->createOverlayComponent (c, layout);
addAndMakeVisible (overlay);
isNewOverlay = true;
}
if (lastOverlay != nullptr)
overlay->toBehind (lastOverlay);
else
overlay->toFront (false);
lastOverlay = overlay;
subCompHolder->addAndMakeVisible (c);
if (lastComp != nullptr)
c->toBehind (lastComp);
else
c->toFront (false);
lastComp = c;
c->setWantsKeyboardFocus (false);
c->setFocusContainerType (FocusContainerType::keyboardFocusContainer);
if (isNewOverlay)
overlay->updateBoundsToMatchTarget();
}
if (grid.updateFromDesign (document))
subCompHolder->repaint();
subCompHolder->setBounds (getComponentArea());
subCompHolder->resized();
}
void ComponentLayoutEditor::mouseDown (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
auto commandManager = &ProjucerApplication::getCommandManager();
PopupMenu m;
m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
m.addSeparator();
for (int i = 0; i < ObjectTypes::numComponentTypes; ++i)
m.addCommandItem (commandManager, JucerCommandIDs::newComponentBase + i);
m.showMenuAsync (PopupMenu::Options());
}
else
{
addChildComponent (lassoComp);
lassoComp.beginLasso (e, this);
}
}
void ComponentLayoutEditor::mouseDrag (const MouseEvent& e)
{
lassoComp.toFront (false);
lassoComp.dragLasso (e);
}
void ComponentLayoutEditor::mouseUp (const MouseEvent& e)
{
lassoComp.endLasso();
removeChildComponent (&lassoComp);
if (! (e.mouseWasDraggedSinceMouseDown() || e.mods.isAnyModifierKeyDown()))
layout.getSelectedSet().deselectAll();
}
static void moveOrStretch (ComponentLayout& layout, int x, int y, bool snap, bool stretch)
{
if (stretch)
layout.stretchSelectedComps (x, y, snap);
else
layout.moveSelectedComps (x, y, snap);
}
bool ComponentLayoutEditor::keyPressed (const KeyPress& key)
{
const bool snap = key.getModifiers().isAltDown();
const bool stretch = key.getModifiers().isShiftDown();
const int amount = snap ? document.getSnappingGridSize() + 1
: 1;
if (key.isKeyCode (KeyPress::rightKey))
{
moveOrStretch (layout, amount, 0, snap, stretch);
}
else if (key.isKeyCode (KeyPress::downKey))
{
moveOrStretch (layout, 0,amount, snap, stretch);
}
else if (key.isKeyCode (KeyPress::leftKey))
{
moveOrStretch (layout, -amount, 0, snap, stretch);
}
else if (key.isKeyCode (KeyPress::upKey))
{
moveOrStretch (layout, 0, -amount, snap, stretch);
}
else
{
return false;
}
return true;
}
bool ComponentLayoutEditor::isInterestedInFileDrag (const StringArray& filenames)
{
const File f (filenames [0]);
return f.hasFileExtension (cppFileExtensions);
}
void ComponentLayoutEditor::filesDropped (const StringArray& filenames, int x, int y)
{
const File f (filenames [0]);
if (JucerDocument::isValidJucerCppFile (f))
{
JucerComponentHandler jucerDocHandler;
layout.getDocument()->beginTransaction();
if (TestComponent* newOne = dynamic_cast<TestComponent*> (layout.addNewComponent (&jucerDocHandler,
x - subCompHolder->getX(),
y - subCompHolder->getY())))
{
JucerComponentHandler::setJucerComponentFile (*layout.getDocument(), newOne,
f.getRelativePathFrom (document.getCppFile().getParentDirectory()));
layout.getSelectedSet().selectOnly (newOne);
}
layout.getDocument()->beginTransaction();
}
}
bool ComponentLayoutEditor::isInterestedInDragSource (const SourceDetails& dragSourceDetails)
{
if (dragSourceDetails.description != projectItemDragType)
return false;
OwnedArray<Project::Item> selectedNodes;
ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);
return selectedNodes.size() > 0;
}
void ComponentLayoutEditor::itemDropped (const SourceDetails& dragSourceDetails)
{
OwnedArray<Project::Item> selectedNodes;
ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);
StringArray filenames;
for (int i = 0; i < selectedNodes.size(); ++i)
if (selectedNodes.getUnchecked(i)->getFile().hasFileExtension (cppFileExtensions))
filenames.add (selectedNodes.getUnchecked(i)->getFile().getFullPathName());
filesDropped (filenames, dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
}
ComponentOverlayComponent* ComponentLayoutEditor::getOverlayCompFor (Component* compToFind) const
{
for (int i = getNumChildComponents(); --i >= 0;)
{
if (ComponentOverlayComponent* const overlay = dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)))
if (overlay->target == compToFind)
return overlay;
}
return nullptr;
}
void ComponentLayoutEditor::findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area)
{
const Rectangle<int> lasso (area - subCompHolder->getPosition());
for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i)
{
Component* c = subCompHolder->getChildComponent (i);
if (c->getBounds().intersects (lasso))
results.add (c);
}
}
SelectedItemSet <Component*>& ComponentLayoutEditor::getLassoSelection()
{
return layout.getSelectedSet();
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../Application/jucer_Application.h"
#include "jucer_ComponentLayoutEditor.h"
#include "../UI/jucer_JucerCommandIDs.h"
#include "../jucer_ObjectTypes.h"
#include "../Components/jucer_JucerComponentHandler.h"
//==============================================================================
class SubComponentHolderComp : public Component
{
public:
SubComponentHolderComp (JucerDocument& doc,
SnapGridPainter& g)
: document (doc), grid (g),
dontFillBackground (false)
{
setInterceptsMouseClicks (false, false);
setWantsKeyboardFocus (false);
setFocusContainerType (FocusContainerType::keyboardFocusContainer);
}
void paint (Graphics& g) override
{
if (! dontFillBackground)
{
if (PaintRoutine* const background = document.getPaintRoutine (0))
{
background->fillWithBackground (g, false);
background->drawElements (g, getLocalBounds());
grid.draw (g, background);
}
else
{
grid.draw (g, nullptr);
}
}
}
void resized() override
{
if (! getBounds().isEmpty())
{
int numTimesToTry = 10;
while (--numTimesToTry >= 0)
{
bool anyCompsMoved = false;
for (int i = 0; i < getNumChildComponents(); ++i)
{
Component* comp = getChildComponent (i);
if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp))
{
const Rectangle<int> newBounds (type->getComponentPosition (comp)
.getRectangle (getLocalBounds(),
document.getComponentLayout()));
anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds);
comp->setBounds (newBounds);
}
}
// repeat this loop until they've all stopped shuffling (might require a few
// loops for all the relative positioned comps to settle down)
if (! anyCompsMoved)
break;
}
}
}
void moved() override
{
((ComponentLayoutEditor*) getParentComponent())->updateOverlayPositions();
}
JucerDocument& document;
SnapGridPainter& grid;
bool dontFillBackground;
};
//==============================================================================
ComponentLayoutEditor::ComponentLayoutEditor (JucerDocument& doc, ComponentLayout& cl)
: document (doc), layout (cl), firstResize (true)
{
setWantsKeyboardFocus (true);
addAndMakeVisible (subCompHolder = new SubComponentHolderComp (document, grid));
refreshAllComponents();
setSize (document.getInitialWidth(),
document.getInitialHeight());
}
ComponentLayoutEditor::~ComponentLayoutEditor()
{
document.removeChangeListener (this);
removeChildComponent (&lassoComp);
deleteAllChildren();
}
//==============================================================================
void ComponentLayoutEditor::visibilityChanged()
{
document.beginTransaction();
if (isVisible())
{
refreshAllComponents();
document.addChangeListener (this);
}
else
{
document.removeChangeListener (this);
}
}
void ComponentLayoutEditor::changeListenerCallback (ChangeBroadcaster*)
{
refreshAllComponents();
}
void ComponentLayoutEditor::paint (Graphics&)
{
}
void ComponentLayoutEditor::resized()
{
if (firstResize && getWidth() > 0 && getHeight() > 0)
{
firstResize = false;
refreshAllComponents();
}
subCompHolder->setBounds (getComponentArea());
updateOverlayPositions();
}
Rectangle<int> ComponentLayoutEditor::getComponentArea() const
{
const int editorEdgeGap = 4;
if (document.isFixedSize())
return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2,
(getHeight() - document.getInitialHeight()) / 2,
document.getInitialWidth(),
document.getInitialHeight());
return Rectangle<int> (editorEdgeGap, editorEdgeGap,
getWidth() - editorEdgeGap * 2,
getHeight() - editorEdgeGap * 2);
}
Image ComponentLayoutEditor::createComponentLayerSnapshot() const
{
((SubComponentHolderComp*) subCompHolder)->dontFillBackground = true;
Image im = subCompHolder->createComponentSnapshot (Rectangle<int> (0, 0, subCompHolder->getWidth(), subCompHolder->getHeight()));
((SubComponentHolderComp*) subCompHolder)->dontFillBackground = false;
return im;
}
void ComponentLayoutEditor::updateOverlayPositions()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (ComponentOverlayComponent* const overlay = dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)))
overlay->updateBoundsToMatchTarget();
}
void ComponentLayoutEditor::refreshAllComponents()
{
for (int i = getNumChildComponents(); --i >= 0;)
{
std::unique_ptr<ComponentOverlayComponent> overlay (dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)));
if (overlay != nullptr && layout.containsComponent (overlay->target))
overlay.release();
}
for (int i = subCompHolder->getNumChildComponents(); --i >= 0;)
{
Component* const comp = subCompHolder->getChildComponent (i);
if (! layout.containsComponent (comp))
subCompHolder->removeChildComponent (comp);
}
Component* lastComp = nullptr;
Component* lastOverlay = nullptr;
for (int i = layout.getNumComponents(); --i >= 0;)
{
auto c = layout.getComponent (i);
jassert (c != nullptr);
auto overlay = getOverlayCompFor (c);
bool isNewOverlay = false;
if (overlay == nullptr)
{
auto handler = ComponentTypeHandler::getHandlerFor (*c);
jassert (handler != nullptr);
overlay = handler->createOverlayComponent (c, layout);
addAndMakeVisible (overlay);
isNewOverlay = true;
}
if (lastOverlay != nullptr)
overlay->toBehind (lastOverlay);
else
overlay->toFront (false);
lastOverlay = overlay;
subCompHolder->addAndMakeVisible (c);
if (lastComp != nullptr)
c->toBehind (lastComp);
else
c->toFront (false);
lastComp = c;
c->setWantsKeyboardFocus (false);
c->setFocusContainerType (FocusContainerType::keyboardFocusContainer);
if (isNewOverlay)
overlay->updateBoundsToMatchTarget();
}
if (grid.updateFromDesign (document))
subCompHolder->repaint();
subCompHolder->setBounds (getComponentArea());
subCompHolder->resized();
}
void ComponentLayoutEditor::mouseDown (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
auto commandManager = &ProjucerApplication::getCommandManager();
PopupMenu m;
m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
m.addSeparator();
for (int i = 0; i < ObjectTypes::numComponentTypes; ++i)
m.addCommandItem (commandManager, JucerCommandIDs::newComponentBase + i);
m.showMenuAsync (PopupMenu::Options());
}
else
{
addChildComponent (lassoComp);
lassoComp.beginLasso (e, this);
}
}
void ComponentLayoutEditor::mouseDrag (const MouseEvent& e)
{
lassoComp.toFront (false);
lassoComp.dragLasso (e);
}
void ComponentLayoutEditor::mouseUp (const MouseEvent& e)
{
lassoComp.endLasso();
removeChildComponent (&lassoComp);
if (! (e.mouseWasDraggedSinceMouseDown() || e.mods.isAnyModifierKeyDown()))
layout.getSelectedSet().deselectAll();
}
static void moveOrStretch (ComponentLayout& layout, int x, int y, bool snap, bool stretch)
{
if (stretch)
layout.stretchSelectedComps (x, y, snap);
else
layout.moveSelectedComps (x, y, snap);
}
bool ComponentLayoutEditor::keyPressed (const KeyPress& key)
{
const bool snap = key.getModifiers().isAltDown();
const bool stretch = key.getModifiers().isShiftDown();
const int amount = snap ? document.getSnappingGridSize() + 1
: 1;
if (key.isKeyCode (KeyPress::rightKey))
{
moveOrStretch (layout, amount, 0, snap, stretch);
}
else if (key.isKeyCode (KeyPress::downKey))
{
moveOrStretch (layout, 0,amount, snap, stretch);
}
else if (key.isKeyCode (KeyPress::leftKey))
{
moveOrStretch (layout, -amount, 0, snap, stretch);
}
else if (key.isKeyCode (KeyPress::upKey))
{
moveOrStretch (layout, 0, -amount, snap, stretch);
}
else
{
return false;
}
return true;
}
bool ComponentLayoutEditor::isInterestedInFileDrag (const StringArray& filenames)
{
const File f (filenames [0]);
return f.hasFileExtension (cppFileExtensions);
}
void ComponentLayoutEditor::filesDropped (const StringArray& filenames, int x, int y)
{
const File f (filenames [0]);
if (JucerDocument::isValidJucerCppFile (f))
{
JucerComponentHandler jucerDocHandler;
layout.getDocument()->beginTransaction();
if (TestComponent* newOne = dynamic_cast<TestComponent*> (layout.addNewComponent (&jucerDocHandler,
x - subCompHolder->getX(),
y - subCompHolder->getY())))
{
JucerComponentHandler::setJucerComponentFile (*layout.getDocument(), newOne,
f.getRelativePathFrom (document.getCppFile().getParentDirectory()));
layout.getSelectedSet().selectOnly (newOne);
}
layout.getDocument()->beginTransaction();
}
}
bool ComponentLayoutEditor::isInterestedInDragSource (const SourceDetails& dragSourceDetails)
{
if (dragSourceDetails.description != projectItemDragType)
return false;
OwnedArray<Project::Item> selectedNodes;
ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);
return selectedNodes.size() > 0;
}
void ComponentLayoutEditor::itemDropped (const SourceDetails& dragSourceDetails)
{
OwnedArray<Project::Item> selectedNodes;
ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);
StringArray filenames;
for (int i = 0; i < selectedNodes.size(); ++i)
if (selectedNodes.getUnchecked(i)->getFile().hasFileExtension (cppFileExtensions))
filenames.add (selectedNodes.getUnchecked(i)->getFile().getFullPathName());
filesDropped (filenames, dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
}
ComponentOverlayComponent* ComponentLayoutEditor::getOverlayCompFor (Component* compToFind) const
{
for (int i = getNumChildComponents(); --i >= 0;)
{
if (ComponentOverlayComponent* const overlay = dynamic_cast<ComponentOverlayComponent*> (getChildComponent (i)))
if (overlay->target == compToFind)
return overlay;
}
return nullptr;
}
void ComponentLayoutEditor::findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area)
{
const Rectangle<int> lasso (area - subCompHolder->getPosition());
for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i)
{
Component* c = subCompHolder->getChildComponent (i);
if (c->getBounds().intersects (lasso))
results.add (c);
}
}
SelectedItemSet <Component*>& ComponentLayoutEditor::getLassoSelection()
{
return layout.getSelectedSet();
}

View File

@ -1,86 +1,86 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_ComponentOverlayComponent.h"
#include "../jucer_JucerDocument.h"
#include "jucer_SnapGridPainter.h"
//==============================================================================
class ComponentLayoutEditor : public Component,
public FileDragAndDropTarget,
public DragAndDropTarget,
public LassoSource<Component*>,
private ChangeListener
{
public:
//==============================================================================
ComponentLayoutEditor (JucerDocument&, ComponentLayout&);
~ComponentLayoutEditor() override;
//==============================================================================
void paint (Graphics&) override;
void resized() override;
void visibilityChanged() override;
void mouseDown (const MouseEvent&) override;
void mouseDrag (const MouseEvent&) override;
void mouseUp (const MouseEvent&) override;
bool keyPressed (const KeyPress&) override;
bool isInterestedInFileDrag (const StringArray& files) override;
void filesDropped (const StringArray& filenames, int x, int y) override;
bool isInterestedInDragSource (const SourceDetails& dragSourceDetails) override;
void itemDropped (const SourceDetails& dragSourceDetails) override;
ComponentLayout& getLayout() const noexcept { return layout; }
void findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area) override;
SelectedItemSet<Component*>& getLassoSelection() override;
//==============================================================================
void refreshAllComponents();
void updateOverlayPositions();
ComponentOverlayComponent* getOverlayCompFor (Component*) const;
Rectangle<int> getComponentArea() const;
Image createComponentLayerSnapshot() const;
private:
void changeListenerCallback (ChangeBroadcaster*) override;
JucerDocument& document;
ComponentLayout& layout;
Component* subCompHolder;
LassoComponent<Component*> lassoComp;
SnapGridPainter grid;
bool firstResize;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_ComponentOverlayComponent.h"
#include "../jucer_JucerDocument.h"
#include "jucer_SnapGridPainter.h"
//==============================================================================
class ComponentLayoutEditor : public Component,
public FileDragAndDropTarget,
public DragAndDropTarget,
public LassoSource<Component*>,
private ChangeListener
{
public:
//==============================================================================
ComponentLayoutEditor (JucerDocument&, ComponentLayout&);
~ComponentLayoutEditor() override;
//==============================================================================
void paint (Graphics&) override;
void resized() override;
void visibilityChanged() override;
void mouseDown (const MouseEvent&) override;
void mouseDrag (const MouseEvent&) override;
void mouseUp (const MouseEvent&) override;
bool keyPressed (const KeyPress&) override;
bool isInterestedInFileDrag (const StringArray& files) override;
void filesDropped (const StringArray& filenames, int x, int y) override;
bool isInterestedInDragSource (const SourceDetails& dragSourceDetails) override;
void itemDropped (const SourceDetails& dragSourceDetails) override;
ComponentLayout& getLayout() const noexcept { return layout; }
void findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area) override;
SelectedItemSet<Component*>& getLassoSelection() override;
//==============================================================================
void refreshAllComponents();
void updateOverlayPositions();
ComponentOverlayComponent* getOverlayCompFor (Component*) const;
Rectangle<int> getComponentArea() const;
Image createComponentLayerSnapshot() const;
private:
void changeListenerCallback (ChangeBroadcaster*) override;
JucerDocument& document;
ComponentLayout& layout;
Component* subCompHolder;
LassoComponent<Component*> lassoComp;
SnapGridPainter grid;
bool firstResize;
};

View File

@ -1,118 +1,118 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_ComponentLayoutEditor.h"
#include "jucer_EditingPanelBase.h"
//==============================================================================
class ComponentLayoutPanel : public EditingPanelBase
{
public:
//==============================================================================
ComponentLayoutPanel (JucerDocument& doc, ComponentLayout& l)
: EditingPanelBase (doc,
new LayoutPropsPanel (doc, l),
new ComponentLayoutEditor (doc, l)),
layout (l)
{
}
~ComponentLayoutPanel()
{
deleteAllChildren();
}
void updatePropertiesList()
{
((LayoutPropsPanel*) propsPanel)->updateList();
}
Rectangle<int> getComponentArea() const
{
return ((ComponentLayoutEditor*) editor)->getComponentArea();
}
Image createComponentSnapshot() const
{
return ((ComponentLayoutEditor*) editor)->createComponentLayerSnapshot();
}
ComponentLayout& layout;
private:
class LayoutPropsPanel : public Component,
private ChangeListener
{
public:
LayoutPropsPanel (JucerDocument& doc, ComponentLayout& l)
: document (doc), layout (l)
{
layout.getSelectedSet().addChangeListener (this);
addAndMakeVisible (propsPanel);
}
~LayoutPropsPanel() override
{
layout.getSelectedSet().removeChangeListener (this);
clear();
}
void resized() override
{
propsPanel.setBounds (4, 4, getWidth() - 8, getHeight() - 8);
}
void clear()
{
propsPanel.clear();
}
void updateList()
{
clear();
auto numSelected = layout.getSelectedSet().getNumSelected();
if (numSelected > 0) // xxx need to cope with multiple
{
if (auto* comp = layout.getSelectedSet().getSelectedItem (0))
if (auto* type = ComponentTypeHandler::getHandlerFor (*comp))
type->addPropertiesToPropertyPanel (comp, document, propsPanel, numSelected > 1);
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
updateList();
}
JucerDocument& document;
ComponentLayout& layout;
PropertyPanel propsPanel;
};
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_ComponentLayoutEditor.h"
#include "jucer_EditingPanelBase.h"
//==============================================================================
class ComponentLayoutPanel : public EditingPanelBase
{
public:
//==============================================================================
ComponentLayoutPanel (JucerDocument& doc, ComponentLayout& l)
: EditingPanelBase (doc,
new LayoutPropsPanel (doc, l),
new ComponentLayoutEditor (doc, l)),
layout (l)
{
}
~ComponentLayoutPanel()
{
deleteAllChildren();
}
void updatePropertiesList()
{
((LayoutPropsPanel*) propsPanel)->updateList();
}
Rectangle<int> getComponentArea() const
{
return ((ComponentLayoutEditor*) editor)->getComponentArea();
}
Image createComponentSnapshot() const
{
return ((ComponentLayoutEditor*) editor)->createComponentLayerSnapshot();
}
ComponentLayout& layout;
private:
class LayoutPropsPanel : public Component,
private ChangeListener
{
public:
LayoutPropsPanel (JucerDocument& doc, ComponentLayout& l)
: document (doc), layout (l)
{
layout.getSelectedSet().addChangeListener (this);
addAndMakeVisible (propsPanel);
}
~LayoutPropsPanel() override
{
layout.getSelectedSet().removeChangeListener (this);
clear();
}
void resized() override
{
propsPanel.setBounds (4, 4, getWidth() - 8, getHeight() - 8);
}
void clear()
{
propsPanel.clear();
}
void updateList()
{
clear();
auto numSelected = layout.getSelectedSet().getNumSelected();
if (numSelected > 0) // xxx need to cope with multiple
{
if (auto* comp = layout.getSelectedSet().getSelectedItem (0))
if (auto* type = ComponentTypeHandler::getHandlerFor (*comp))
type->addPropertiesToPropertyPanel (comp, document, propsPanel, numSelected > 1);
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
updateList();
}
JucerDocument& document;
ComponentLayout& layout;
PropertyPanel propsPanel;
};
};

View File

@ -1,278 +1,278 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_ComponentLayoutEditor.h"
#include "../jucer_UtilityFunctions.h"
//==============================================================================
ComponentOverlayComponent::ComponentOverlayComponent (Component* const target_,
ComponentLayout& layout_)
: target (target_),
borderThickness (4),
layout (layout_),
selected (false),
dragging (false),
originalAspectRatio (1.0)
{
setMinimumOnscreenAmounts (0, 0, 0, 0);
setSizeLimits (borderThickness * 2 + 2, borderThickness * 2 + 2, 8192, 8192);
border.reset (new ResizableBorderComponent (this, this));
addChildComponent (border.get());
border->setBorderThickness (BorderSize<int> (borderThickness));
target->addComponentListener (this);
changeListenerCallback (nullptr);
layout.getSelectedSet().addChangeListener (this);
setRepaintsOnMouseActivity (true);
border->setRepaintsOnMouseActivity (true);
}
ComponentOverlayComponent::~ComponentOverlayComponent()
{
layout.getSelectedSet().removeChangeListener (this);
if (target != nullptr)
target->removeComponentListener (this);
}
void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*)
{
const bool nowSelected = layout.getSelectedSet().isSelected (target);
if (selected != nowSelected)
{
selected = nowSelected;
border->setVisible (nowSelected);
repaint();
}
}
void ComponentOverlayComponent::paint (Graphics& g)
{
jassert (target != nullptr);
border->setColour (backgroundColourId, Colours::transparentBlack);
if (selected)
{
auto selectedItems = layout.getSelectedSet();
auto baseColour = findColour (defaultHighlightColourId);
const BorderSize<int> borderSize (border->getBorderThickness());
drawResizableBorder (g, getWidth(), getHeight(), borderSize,
(isMouseOverOrDragging() || border->isMouseOverOrDragging()),
baseColour.withAlpha (selectedItems.getSelectedItem (0) == target ? 1.0f : 0.3f));
}
else if (isMouseOverOrDragging())
{
drawMouseOverCorners (g, getWidth(), getHeight());
}
}
void ComponentOverlayComponent::resized()
{
jassert (target != nullptr);
border->setBounds (getLocalBounds());
}
void ComponentOverlayComponent::mouseDown (const MouseEvent& e)
{
dragging = false;
mouseDownSelectStatus = layout.getSelectedSet().addToSelectionOnMouseDown (target, e.mods);
if (e.mods.isPopupMenu())
{
showPopupMenu();
return; // this may be deleted now..
}
}
void ComponentOverlayComponent::mouseDrag (const MouseEvent& e)
{
if (! e.mods.isPopupMenu())
{
if (selected && ! dragging)
{
dragging = e.mouseWasDraggedSinceMouseDown();
if (dragging)
layout.startDragging();
}
if (dragging)
{
layout.dragSelectedComps (e.getDistanceFromDragStartX(),
e.getDistanceFromDragStartY());
}
}
}
void ComponentOverlayComponent::mouseUp (const MouseEvent& e)
{
if (dragging)
layout.endDragging();
layout.getSelectedSet().addToSelectionOnMouseUp (target, e.mods, dragging, mouseDownSelectStatus);
}
void ComponentOverlayComponent::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/)
{
updateBoundsToMatchTarget();
}
void ComponentOverlayComponent::updateBoundsToMatchTarget()
{
if (Component* const parent = target->getParentComponent())
{
const int dx = parent->getX();
const int dy = parent->getY();
setBounds (dx + target->getX() - borderThickness,
dy + target->getY() - borderThickness,
target->getWidth() + borderThickness * 2,
target->getHeight() + borderThickness * 2);
}
if (border->isMouseButtonDown())
layout.changed();
}
void ComponentOverlayComponent::resizeStart()
{
if (getHeight() > 0)
originalAspectRatio = getWidth() / (double) getHeight();
else
originalAspectRatio = 1.0;
layout.getDocument()->beginTransaction ("Resize components");
}
void ComponentOverlayComponent::resizeEnd()
{
layout.getDocument()->beginTransaction();
}
void ComponentOverlayComponent::checkBounds (Rectangle<int>& b,
const Rectangle<int>& previousBounds,
const Rectangle<int>& limits,
const bool isStretchingTop,
const bool isStretchingLeft,
const bool isStretchingBottom,
const bool isStretchingRight)
{
if (ModifierKeys::currentModifiers.isShiftDown())
setFixedAspectRatio (originalAspectRatio);
else
setFixedAspectRatio (0.0);
ComponentBoundsConstrainer::checkBounds (b, previousBounds, limits, isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight);
if (layout.getDocument()->isSnapActive (true))
{
if (Component* const parent = target->getParentComponent())
{
const int dx = parent->getX();
const int dy = parent->getY();
int x = b.getX();
int y = b.getY();
int w = b.getWidth();
int h = b.getHeight();
x += borderThickness - dx;
y += borderThickness - dy;
w -= borderThickness * 2;
h -= borderThickness * 2;
int right = x + w;
int bottom = y + h;
if (isStretchingRight)
right = layout.getDocument()->snapPosition (right);
if (isStretchingBottom)
bottom = layout.getDocument()->snapPosition (bottom);
if (isStretchingLeft)
x = layout.getDocument()->snapPosition (x);
if (isStretchingTop)
y = layout.getDocument()->snapPosition (y);
w = (right - x) + borderThickness * 2;
h = (bottom - y) + borderThickness * 2;
x -= borderThickness - dx;
y -= borderThickness - dy;
b = Rectangle<int> (x, y, w, h);
}
}
}
void ComponentOverlayComponent::applyBoundsToComponent (Component& component, Rectangle<int> b)
{
if (component.getBounds() != b)
{
layout.getDocument()->getUndoManager().undoCurrentTransactionOnly();
auto dX = b.getX() - component.getX();
auto dY = b.getY() - component.getY();
auto dW = b.getWidth() - component.getWidth();
auto dH = b.getHeight() - component.getHeight();
component.setBounds (b);
if (auto* parent = target->getParentComponent())
target->setBounds (b.getX() + borderThickness - parent->getX(),
b.getY() + borderThickness - parent->getY(),
b.getWidth() - borderThickness * 2,
b.getHeight() - borderThickness * 2);
layout.updateStoredComponentPosition (target, true);
if (layout.getSelectedSet().getNumSelected() > 1)
{
for (auto s : layout.getSelectedSet())
{
if (s != target)
{
s->setBounds (s->getX() + dX, s->getY() + dY, s->getWidth() + dW, s->getHeight() + dH);
layout.updateStoredComponentPosition (s, true);
}
}
}
}
}
void ComponentOverlayComponent::showPopupMenu()
{
ComponentTypeHandler::getHandlerFor (*target)->showPopupMenu (target, layout);
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_ComponentLayoutEditor.h"
#include "../jucer_UtilityFunctions.h"
//==============================================================================
ComponentOverlayComponent::ComponentOverlayComponent (Component* const target_,
ComponentLayout& layout_)
: target (target_),
borderThickness (4),
layout (layout_),
selected (false),
dragging (false),
originalAspectRatio (1.0)
{
setMinimumOnscreenAmounts (0, 0, 0, 0);
setSizeLimits (borderThickness * 2 + 2, borderThickness * 2 + 2, 8192, 8192);
border.reset (new ResizableBorderComponent (this, this));
addChildComponent (border.get());
border->setBorderThickness (BorderSize<int> (borderThickness));
target->addComponentListener (this);
changeListenerCallback (nullptr);
layout.getSelectedSet().addChangeListener (this);
setRepaintsOnMouseActivity (true);
border->setRepaintsOnMouseActivity (true);
}
ComponentOverlayComponent::~ComponentOverlayComponent()
{
layout.getSelectedSet().removeChangeListener (this);
if (target != nullptr)
target->removeComponentListener (this);
}
void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*)
{
const bool nowSelected = layout.getSelectedSet().isSelected (target);
if (selected != nowSelected)
{
selected = nowSelected;
border->setVisible (nowSelected);
repaint();
}
}
void ComponentOverlayComponent::paint (Graphics& g)
{
jassert (target != nullptr);
border->setColour (backgroundColourId, Colours::transparentBlack);
if (selected)
{
auto selectedItems = layout.getSelectedSet();
auto baseColour = findColour (defaultHighlightColourId);
const BorderSize<int> borderSize (border->getBorderThickness());
drawResizableBorder (g, getWidth(), getHeight(), borderSize,
(isMouseOverOrDragging() || border->isMouseOverOrDragging()),
baseColour.withAlpha (selectedItems.getSelectedItem (0) == target ? 1.0f : 0.3f));
}
else if (isMouseOverOrDragging())
{
drawMouseOverCorners (g, getWidth(), getHeight());
}
}
void ComponentOverlayComponent::resized()
{
jassert (target != nullptr);
border->setBounds (getLocalBounds());
}
void ComponentOverlayComponent::mouseDown (const MouseEvent& e)
{
dragging = false;
mouseDownSelectStatus = layout.getSelectedSet().addToSelectionOnMouseDown (target, e.mods);
if (e.mods.isPopupMenu())
{
showPopupMenu();
return; // this may be deleted now..
}
}
void ComponentOverlayComponent::mouseDrag (const MouseEvent& e)
{
if (! e.mods.isPopupMenu())
{
if (selected && ! dragging)
{
dragging = e.mouseWasDraggedSinceMouseDown();
if (dragging)
layout.startDragging();
}
if (dragging)
{
layout.dragSelectedComps (e.getDistanceFromDragStartX(),
e.getDistanceFromDragStartY());
}
}
}
void ComponentOverlayComponent::mouseUp (const MouseEvent& e)
{
if (dragging)
layout.endDragging();
layout.getSelectedSet().addToSelectionOnMouseUp (target, e.mods, dragging, mouseDownSelectStatus);
}
void ComponentOverlayComponent::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/)
{
updateBoundsToMatchTarget();
}
void ComponentOverlayComponent::updateBoundsToMatchTarget()
{
if (Component* const parent = target->getParentComponent())
{
const int dx = parent->getX();
const int dy = parent->getY();
setBounds (dx + target->getX() - borderThickness,
dy + target->getY() - borderThickness,
target->getWidth() + borderThickness * 2,
target->getHeight() + borderThickness * 2);
}
if (border->isMouseButtonDown())
layout.changed();
}
void ComponentOverlayComponent::resizeStart()
{
if (getHeight() > 0)
originalAspectRatio = getWidth() / (double) getHeight();
else
originalAspectRatio = 1.0;
layout.getDocument()->beginTransaction ("Resize components");
}
void ComponentOverlayComponent::resizeEnd()
{
layout.getDocument()->beginTransaction();
}
void ComponentOverlayComponent::checkBounds (Rectangle<int>& b,
const Rectangle<int>& previousBounds,
const Rectangle<int>& limits,
const bool isStretchingTop,
const bool isStretchingLeft,
const bool isStretchingBottom,
const bool isStretchingRight)
{
if (ModifierKeys::currentModifiers.isShiftDown())
setFixedAspectRatio (originalAspectRatio);
else
setFixedAspectRatio (0.0);
ComponentBoundsConstrainer::checkBounds (b, previousBounds, limits, isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight);
if (layout.getDocument()->isSnapActive (true))
{
if (Component* const parent = target->getParentComponent())
{
const int dx = parent->getX();
const int dy = parent->getY();
int x = b.getX();
int y = b.getY();
int w = b.getWidth();
int h = b.getHeight();
x += borderThickness - dx;
y += borderThickness - dy;
w -= borderThickness * 2;
h -= borderThickness * 2;
int right = x + w;
int bottom = y + h;
if (isStretchingRight)
right = layout.getDocument()->snapPosition (right);
if (isStretchingBottom)
bottom = layout.getDocument()->snapPosition (bottom);
if (isStretchingLeft)
x = layout.getDocument()->snapPosition (x);
if (isStretchingTop)
y = layout.getDocument()->snapPosition (y);
w = (right - x) + borderThickness * 2;
h = (bottom - y) + borderThickness * 2;
x -= borderThickness - dx;
y -= borderThickness - dy;
b = Rectangle<int> (x, y, w, h);
}
}
}
void ComponentOverlayComponent::applyBoundsToComponent (Component& component, Rectangle<int> b)
{
if (component.getBounds() != b)
{
layout.getDocument()->getUndoManager().undoCurrentTransactionOnly();
auto dX = b.getX() - component.getX();
auto dY = b.getY() - component.getY();
auto dW = b.getWidth() - component.getWidth();
auto dH = b.getHeight() - component.getHeight();
component.setBounds (b);
if (auto* parent = target->getParentComponent())
target->setBounds (b.getX() + borderThickness - parent->getX(),
b.getY() + borderThickness - parent->getY(),
b.getWidth() - borderThickness * 2,
b.getHeight() - borderThickness * 2);
layout.updateStoredComponentPosition (target, true);
if (layout.getSelectedSet().getNumSelected() > 1)
{
for (auto s : layout.getSelectedSet())
{
if (s != target)
{
s->setBounds (s->getX() + dX, s->getY() + dY, s->getWidth() + dW, s->getHeight() + dH);
layout.updateStoredComponentPosition (s, true);
}
}
}
}
}
void ComponentOverlayComponent::showPopupMenu()
{
ComponentTypeHandler::getHandlerFor (*target)->showPopupMenu (target, layout);
}

View File

@ -1,84 +1,84 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class ComponentOverlayComponent : public Component,
private ComponentBoundsConstrainer,
private ComponentListener,
private ChangeListener
{
public:
//==============================================================================
ComponentOverlayComponent (Component* const targetComponent,
ComponentLayout& layout);
~ComponentOverlayComponent() override;
//==============================================================================
virtual void showPopupMenu();
//==============================================================================
void paint (Graphics&) override;
void resized() override;
void mouseDown (const MouseEvent&) override;
void mouseDrag (const MouseEvent&) override;
void mouseUp (const MouseEvent&) override;
void updateBoundsToMatchTarget();
//==============================================================================
Component::SafePointer<Component> target;
const int borderThickness;
private:
void resizeStart() override;
void resizeEnd() override;
void checkBounds (Rectangle<int>& bounds,
const Rectangle<int>& previousBounds,
const Rectangle<int>& limits,
bool isStretchingTop,
bool isStretchingLeft,
bool isStretchingBottom,
bool isStretchingRight) override;
void applyBoundsToComponent (Component&, Rectangle<int>) override;
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
void changeListenerCallback (ChangeBroadcaster*) override;
std::unique_ptr<ResizableBorderComponent> border;
ComponentLayout& layout;
bool selected, dragging, mouseDownSelectStatus;
double originalAspectRatio;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class ComponentOverlayComponent : public Component,
private ComponentBoundsConstrainer,
private ComponentListener,
private ChangeListener
{
public:
//==============================================================================
ComponentOverlayComponent (Component* const targetComponent,
ComponentLayout& layout);
~ComponentOverlayComponent() override;
//==============================================================================
virtual void showPopupMenu();
//==============================================================================
void paint (Graphics&) override;
void resized() override;
void mouseDown (const MouseEvent&) override;
void mouseDrag (const MouseEvent&) override;
void mouseUp (const MouseEvent&) override;
void updateBoundsToMatchTarget();
//==============================================================================
Component::SafePointer<Component> target;
const int borderThickness;
private:
void resizeStart() override;
void resizeEnd() override;
void checkBounds (Rectangle<int>& bounds,
const Rectangle<int>& previousBounds,
const Rectangle<int>& limits,
bool isStretchingTop,
bool isStretchingLeft,
bool isStretchingBottom,
bool isStretchingRight) override;
void applyBoundsToComponent (Component&, Rectangle<int>) override;
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
void changeListenerCallback (ChangeBroadcaster*) override;
std::unique_ptr<ResizableBorderComponent> border;
ComponentLayout& layout;
bool selected, dragging, mouseDownSelectStatus;
double originalAspectRatio;
};

View File

@ -1,243 +1,243 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_EditingPanelBase.h"
#include "jucer_JucerDocumentEditor.h"
//==============================================================================
class EditingPanelBase::MagnifierComponent : public Component
{
public:
explicit MagnifierComponent (Component* c) : content (c)
{
addAndMakeVisible (content.get());
childBoundsChanged (content.get());
}
void childBoundsChanged (Component* child)
{
auto childArea = getLocalArea (child, child->getLocalBounds());
setSize (childArea.getWidth(), childArea.getHeight());
}
double getScaleFactor() const { return scaleFactor; }
void setScaleFactor (double newScale)
{
scaleFactor = newScale;
content->setTransform (AffineTransform::scale ((float) scaleFactor));
}
private:
double scaleFactor = 1.0;
std::unique_ptr<Component> content;
};
//==============================================================================
class ZoomingViewport : public Viewport
{
public:
explicit ZoomingViewport (EditingPanelBase* p) : panel (p)
{
}
void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
{
if (e.mods.isCtrlDown() || e.mods.isAltDown() || e.mods.isCommandDown())
mouseMagnify (e, 1.0f / (1.0f - wheel.deltaY));
else
Viewport::mouseWheelMove (e, wheel);
}
void mouseMagnify (const MouseEvent& e, float factor)
{
panel->setZoom (panel->getZoom() * factor, e.x, e.y);
}
void dragKeyHeldDown (const bool isKeyDown)
{
if (isSpaceDown != isKeyDown)
{
isSpaceDown = isKeyDown;
if (isSpaceDown)
{
auto dc = new DraggerOverlayComp();
addAndMakeVisible (dc);
dc->setBounds (getLocalBounds());
}
else
{
for (int i = getNumChildComponents(); --i >= 0;)
std::unique_ptr<DraggerOverlayComp> deleter (dynamic_cast<DraggerOverlayComp*> (getChildComponent (i)));
}
}
}
private:
EditingPanelBase* const panel;
bool isSpaceDown = false;
//==============================================================================
class DraggerOverlayComp : public Component
{
public:
DraggerOverlayComp()
{
setMouseCursor (MouseCursor::DraggingHandCursor);
setAlwaysOnTop (true);
}
void mouseDown (const MouseEvent&)
{
if (Viewport* viewport = findParentComponentOfClass<Viewport>())
{
startX = viewport->getViewPositionX();
startY = viewport->getViewPositionY();
}
}
void mouseDrag (const MouseEvent& e)
{
if (Viewport* viewport = findParentComponentOfClass<Viewport>())
viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
startX - e.getDistanceFromDragStartX()),
jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
startY - e.getDistanceFromDragStartY()));
}
private:
int startX, startY;
};
};
//==============================================================================
EditingPanelBase::EditingPanelBase (JucerDocument& doc, Component* props, Component* editorComp)
: document (doc),
editor (editorComp),
propsPanel (props)
{
addAndMakeVisible (viewport = new ZoomingViewport (this));
addAndMakeVisible (propsPanel);
viewport->setViewedComponent (magnifier = new MagnifierComponent (editor));
}
EditingPanelBase::~EditingPanelBase()
{
deleteAllChildren();
}
void EditingPanelBase::resized()
{
const int contentW = jmax (1, getWidth() - 260);
propsPanel->setBounds (contentW + 4, 4, jmax (100, getWidth() - contentW - 8), getHeight() - 8);
viewport->setBounds (4, 4, contentW - 8, getHeight() - 8);
if (document.isFixedSize())
editor->setSize (jmax (document.getInitialWidth(),
roundToInt ((viewport->getWidth() - viewport->getScrollBarThickness()) / getZoom())),
jmax (document.getInitialHeight(),
roundToInt ((viewport->getHeight() - viewport->getScrollBarThickness()) / getZoom())));
else
editor->setSize (viewport->getWidth(),
viewport->getHeight());
}
void EditingPanelBase::paint (Graphics& g)
{
g.fillAll (findColour (secondaryBackgroundColourId));
}
void EditingPanelBase::visibilityChanged()
{
if (isVisible())
{
updatePropertiesList();
if (Component* p = getParentComponent())
{
resized();
if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
cdh->setViewportToLastPos (viewport, *this);
resized();
}
}
else
{
if (Component* p = getParentComponent())
if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
cdh->storeLastViewportPos (viewport, *this);
}
editor->setVisible (isVisible());
}
double EditingPanelBase::getZoom() const
{
return magnifier->getScaleFactor();
}
void EditingPanelBase::setZoom (double newScale)
{
setZoom (jlimit (1.0 / 8.0, 16.0, newScale),
viewport->getWidth() / 2,
viewport->getHeight() / 2);
}
void EditingPanelBase::setZoom (double newScale, int anchorX, int anchorY)
{
Point<int> anchor (editor->getLocalPoint (viewport, Point<int> (anchorX, anchorY)));
magnifier->setScaleFactor (newScale);
resized();
jassert (viewport != nullptr);
anchor = viewport->getLocalPoint (editor, anchor);
viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
viewport->getViewPositionX() + anchor.getX() - anchorX),
jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
viewport->getViewPositionY() + anchor.getY() - anchorY));
}
void EditingPanelBase::xyToTargetXY (int& x, int& y) const
{
Point<int> pos (editor->getLocalPoint (this, Point<int> (x, y)));
x = pos.getX();
y = pos.getY();
}
void EditingPanelBase::dragKeyHeldDown (bool isKeyDown)
{
((ZoomingViewport*) viewport)->dragKeyHeldDown (isKeyDown);
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_EditingPanelBase.h"
#include "jucer_JucerDocumentEditor.h"
//==============================================================================
class EditingPanelBase::MagnifierComponent : public Component
{
public:
explicit MagnifierComponent (Component* c) : content (c)
{
addAndMakeVisible (content.get());
childBoundsChanged (content.get());
}
void childBoundsChanged (Component* child)
{
auto childArea = getLocalArea (child, child->getLocalBounds());
setSize (childArea.getWidth(), childArea.getHeight());
}
double getScaleFactor() const { return scaleFactor; }
void setScaleFactor (double newScale)
{
scaleFactor = newScale;
content->setTransform (AffineTransform::scale ((float) scaleFactor));
}
private:
double scaleFactor = 1.0;
std::unique_ptr<Component> content;
};
//==============================================================================
class ZoomingViewport : public Viewport
{
public:
explicit ZoomingViewport (EditingPanelBase* p) : panel (p)
{
}
void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
{
if (e.mods.isCtrlDown() || e.mods.isAltDown() || e.mods.isCommandDown())
mouseMagnify (e, 1.0f / (1.0f - wheel.deltaY));
else
Viewport::mouseWheelMove (e, wheel);
}
void mouseMagnify (const MouseEvent& e, float factor)
{
panel->setZoom (panel->getZoom() * factor, e.x, e.y);
}
void dragKeyHeldDown (const bool isKeyDown)
{
if (isSpaceDown != isKeyDown)
{
isSpaceDown = isKeyDown;
if (isSpaceDown)
{
auto dc = new DraggerOverlayComp();
addAndMakeVisible (dc);
dc->setBounds (getLocalBounds());
}
else
{
for (int i = getNumChildComponents(); --i >= 0;)
std::unique_ptr<DraggerOverlayComp> deleter (dynamic_cast<DraggerOverlayComp*> (getChildComponent (i)));
}
}
}
private:
EditingPanelBase* const panel;
bool isSpaceDown = false;
//==============================================================================
class DraggerOverlayComp : public Component
{
public:
DraggerOverlayComp()
{
setMouseCursor (MouseCursor::DraggingHandCursor);
setAlwaysOnTop (true);
}
void mouseDown (const MouseEvent&)
{
if (Viewport* viewport = findParentComponentOfClass<Viewport>())
{
startX = viewport->getViewPositionX();
startY = viewport->getViewPositionY();
}
}
void mouseDrag (const MouseEvent& e)
{
if (Viewport* viewport = findParentComponentOfClass<Viewport>())
viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
startX - e.getDistanceFromDragStartX()),
jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
startY - e.getDistanceFromDragStartY()));
}
private:
int startX, startY;
};
};
//==============================================================================
EditingPanelBase::EditingPanelBase (JucerDocument& doc, Component* props, Component* editorComp)
: document (doc),
editor (editorComp),
propsPanel (props)
{
addAndMakeVisible (viewport = new ZoomingViewport (this));
addAndMakeVisible (propsPanel);
viewport->setViewedComponent (magnifier = new MagnifierComponent (editor));
}
EditingPanelBase::~EditingPanelBase()
{
deleteAllChildren();
}
void EditingPanelBase::resized()
{
const int contentW = jmax (1, getWidth() - 260);
propsPanel->setBounds (contentW + 4, 4, jmax (100, getWidth() - contentW - 8), getHeight() - 8);
viewport->setBounds (4, 4, contentW - 8, getHeight() - 8);
if (document.isFixedSize())
editor->setSize (jmax (document.getInitialWidth(),
roundToInt ((viewport->getWidth() - viewport->getScrollBarThickness()) / getZoom())),
jmax (document.getInitialHeight(),
roundToInt ((viewport->getHeight() - viewport->getScrollBarThickness()) / getZoom())));
else
editor->setSize (viewport->getWidth(),
viewport->getHeight());
}
void EditingPanelBase::paint (Graphics& g)
{
g.fillAll (findColour (secondaryBackgroundColourId));
}
void EditingPanelBase::visibilityChanged()
{
if (isVisible())
{
updatePropertiesList();
if (Component* p = getParentComponent())
{
resized();
if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
cdh->setViewportToLastPos (viewport, *this);
resized();
}
}
else
{
if (Component* p = getParentComponent())
if (JucerDocumentEditor* const cdh = dynamic_cast<JucerDocumentEditor*> (p->getParentComponent()))
cdh->storeLastViewportPos (viewport, *this);
}
editor->setVisible (isVisible());
}
double EditingPanelBase::getZoom() const
{
return magnifier->getScaleFactor();
}
void EditingPanelBase::setZoom (double newScale)
{
setZoom (jlimit (1.0 / 8.0, 16.0, newScale),
viewport->getWidth() / 2,
viewport->getHeight() / 2);
}
void EditingPanelBase::setZoom (double newScale, int anchorX, int anchorY)
{
Point<int> anchor (editor->getLocalPoint (viewport, Point<int> (anchorX, anchorY)));
magnifier->setScaleFactor (newScale);
resized();
jassert (viewport != nullptr);
anchor = viewport->getLocalPoint (editor, anchor);
viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()),
viewport->getViewPositionX() + anchor.getX() - anchorX),
jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()),
viewport->getViewPositionY() + anchor.getY() - anchorY));
}
void EditingPanelBase::xyToTargetXY (int& x, int& y) const
{
Point<int> pos (editor->getLocalPoint (this, Point<int> (x, y)));
x = pos.getX();
y = pos.getY();
}
void EditingPanelBase::dragKeyHeldDown (bool isKeyDown)
{
((ZoomingViewport*) viewport)->dragKeyHeldDown (isKeyDown);
}

View File

@ -1,75 +1,75 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "jucer_ComponentLayoutEditor.h"
class LayoutPropsPanel;
//==============================================================================
/**
Base class for the layout and graphics panels - this takes care of arranging
the properties panel and managing the viewport for the content.
*/
class EditingPanelBase : public Component
{
public:
//==============================================================================
EditingPanelBase (JucerDocument& document,
Component* propsPanel,
Component* editorComp);
~EditingPanelBase() override;
//==============================================================================
void resized() override;
void paint (Graphics& g) override;
void visibilityChanged() override;
virtual void updatePropertiesList() = 0;
virtual Rectangle<int> getComponentArea() const = 0;
double getZoom() const;
void setZoom (double newScale);
void setZoom (double newScale, int anchorX, int anchorY);
// convert a pos relative to this component into a pos on the editor
void xyToTargetXY (int& x, int& y) const;
void dragKeyHeldDown (bool isKeyDown);
class MagnifierComponent;
protected:
JucerDocument& document;
Viewport* viewport;
MagnifierComponent* magnifier;
Component* editor;
Component* propsPanel;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "jucer_ComponentLayoutEditor.h"
class LayoutPropsPanel;
//==============================================================================
/**
Base class for the layout and graphics panels - this takes care of arranging
the properties panel and managing the viewport for the content.
*/
class EditingPanelBase : public Component
{
public:
//==============================================================================
EditingPanelBase (JucerDocument& document,
Component* propsPanel,
Component* editorComp);
~EditingPanelBase() override;
//==============================================================================
void resized() override;
void paint (Graphics& g) override;
void visibilityChanged() override;
virtual void updatePropertiesList() = 0;
virtual Rectangle<int> getComponentArea() const = 0;
double getZoom() const;
void setZoom (double newScale);
void setZoom (double newScale, int anchorX, int anchorY);
// convert a pos relative to this component into a pos on the editor
void xyToTargetXY (int& x, int& y) const;
void dragKeyHeldDown (bool isKeyDown);
class MagnifierComponent;
protected:
JucerDocument& document;
Viewport* viewport;
MagnifierComponent* magnifier;
Component* editor;
Component* propsPanel;
};

View File

@ -1,71 +1,71 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
/**
A namespace to hold all the possible command IDs.
*/
namespace JucerCommandIDs
{
enum
{
test = 0xf20009,
toFront = 0xf2000a,
toBack = 0xf2000b,
group = 0xf20017,
ungroup = 0xf20018,
showGrid = 0xf2000e,
enableSnapToGrid = 0xf2000f,
editCompLayout = 0xf20010,
editCompGraphics = 0xf20011,
bringBackLostItems = 0xf20012,
zoomIn = 0xf20013,
zoomOut = 0xf20014,
zoomNormal = 0xf20015,
spaceBarDrag = 0xf20016,
compOverlay0 = 0xf20020,
compOverlay33 = 0xf20021,
compOverlay66 = 0xf20022,
compOverlay100 = 0xf20023,
newDocumentBase = 0xf32001,
newComponentBase = 0xf30001,
newElementBase = 0xf31001,
alignTop = 0xf33000,
alignRight = 0xf33001,
alignBottom = 0xf33002,
alignLeft = 0xf33003,
};
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
/**
A namespace to hold all the possible command IDs.
*/
namespace JucerCommandIDs
{
enum
{
test = 0xf20009,
toFront = 0xf2000a,
toBack = 0xf2000b,
group = 0xf20017,
ungroup = 0xf20018,
showGrid = 0xf2000e,
enableSnapToGrid = 0xf2000f,
editCompLayout = 0xf20010,
editCompGraphics = 0xf20011,
bringBackLostItems = 0xf20012,
zoomIn = 0xf20013,
zoomOut = 0xf20014,
zoomNormal = 0xf20015,
spaceBarDrag = 0xf20016,
compOverlay0 = 0xf20020,
compOverlay33 = 0xf20021,
compOverlay66 = 0xf20022,
compOverlay100 = 0xf20023,
newDocumentBase = 0xf32001,
newComponentBase = 0xf30001,
newElementBase = 0xf31001,
alignTop = 0xf33000,
alignRight = 0xf33001,
alignBottom = 0xf33002,
alignLeft = 0xf33003,
};
}

View File

@ -1,104 +1,104 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "jucer_ComponentLayoutEditor.h"
#include "jucer_PaintRoutineEditor.h"
#include "jucer_ComponentLayoutPanel.h"
//==============================================================================
class JucerDocumentEditor : public Component,
public ApplicationCommandTarget,
private ChangeListener
{
public:
//==============================================================================
JucerDocumentEditor (JucerDocument* const document);
~JucerDocumentEditor() override;
JucerDocument* getDocument() const noexcept { return document.get(); }
void refreshPropertiesPanel() const;
void updateTabs();
void showLayout();
void showGraphics (PaintRoutine* routine);
void setViewportToLastPos (Viewport* vp, EditingPanelBase& editor);
void storeLastViewportPos (Viewport* vp, EditingPanelBase& editor);
Image createComponentLayerSnapshot() const;
//==============================================================================
void paint (Graphics& g) override;
void resized() override;
bool keyPressed (const KeyPress&) override;
//==============================================================================
ApplicationCommandTarget* getNextCommandTarget() override;
void getAllCommands (Array<CommandID>&) override;
void getCommandInfo (CommandID, ApplicationCommandInfo&) override;
bool perform (const InvocationInfo&) override;
static JucerDocumentEditor* getActiveDocumentHolder();
private:
void changeListenerCallback (ChangeBroadcaster*) override;
std::unique_ptr<JucerDocument> document;
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;
void saveLastSelectedTab() const;
void restoreLastSelectedTab();
bool isSomethingSelected() const;
bool areMultipleThingsSelected() const;
// only non-zero if a layout tab is selected
ComponentLayout* getCurrentLayout() const;
// only non-zero if a graphics tab is selected
PaintRoutine* getCurrentPaintRoutine() const;
void setZoom (double scale);
double getZoom() const;
void addElement (int index);
void addComponent (int index);
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "jucer_ComponentLayoutEditor.h"
#include "jucer_PaintRoutineEditor.h"
#include "jucer_ComponentLayoutPanel.h"
//==============================================================================
class JucerDocumentEditor : public Component,
public ApplicationCommandTarget,
private ChangeListener
{
public:
//==============================================================================
JucerDocumentEditor (JucerDocument* const document);
~JucerDocumentEditor() override;
JucerDocument* getDocument() const noexcept { return document.get(); }
void refreshPropertiesPanel() const;
void updateTabs();
void showLayout();
void showGraphics (PaintRoutine* routine);
void setViewportToLastPos (Viewport* vp, EditingPanelBase& editor);
void storeLastViewportPos (Viewport* vp, EditingPanelBase& editor);
Image createComponentLayerSnapshot() const;
//==============================================================================
void paint (Graphics& g) override;
void resized() override;
bool keyPressed (const KeyPress&) override;
//==============================================================================
ApplicationCommandTarget* getNextCommandTarget() override;
void getAllCommands (Array<CommandID>&) override;
void getCommandInfo (CommandID, ApplicationCommandInfo&) override;
bool perform (const InvocationInfo&) override;
static JucerDocumentEditor* getActiveDocumentHolder();
private:
void changeListenerCallback (ChangeBroadcaster*) override;
std::unique_ptr<JucerDocument> document;
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;
void saveLastSelectedTab() const;
void restoreLastSelectedTab();
bool isSomethingSelected() const;
bool areMultipleThingsSelected() const;
// only non-zero if a layout tab is selected
ComponentLayout* getCurrentLayout() const;
// only non-zero if a graphics tab is selected
PaintRoutine* getCurrentPaintRoutine() const;
void setZoom (double scale);
double getZoom() const;
void addElement (int index);
void addComponent (int index);
};

View File

@ -1,281 +1,281 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../Application/jucer_Application.h"
#include "../UI/jucer_JucerCommandIDs.h"
#include "jucer_PaintRoutineEditor.h"
#include "../jucer_ObjectTypes.h"
#include "jucer_JucerDocumentEditor.h"
//==============================================================================
PaintRoutineEditor::PaintRoutineEditor (PaintRoutine& pr, JucerDocument& doc,
JucerDocumentEditor* docHolder)
: graphics (pr),
document (doc),
documentHolder (docHolder),
componentOverlay (nullptr),
componentOverlayOpacity (0.0f)
{
refreshAllElements();
setSize (document.getInitialWidth(),
document.getInitialHeight());
}
PaintRoutineEditor::~PaintRoutineEditor()
{
document.removeChangeListener (this);
removeAllElementComps();
removeChildComponent (&lassoComp);
deleteAllChildren();
}
void PaintRoutineEditor::removeAllElementComps()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
removeChildComponent (e);
}
Rectangle<int> PaintRoutineEditor::getComponentArea() const
{
if (document.isFixedSize())
return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2,
(getHeight() - document.getInitialHeight()) / 2,
document.getInitialWidth(),
document.getInitialHeight());
return getLocalBounds().reduced (4);
}
//==============================================================================
void PaintRoutineEditor::paint (Graphics& g)
{
const Rectangle<int> clip (getComponentArea());
g.reduceClipRegion (clip);
g.setOrigin (clip.getPosition());
graphics.fillWithBackground (g, true);
grid.draw (g, &graphics);
}
void PaintRoutineEditor::paintOverChildren (Graphics& g)
{
if (componentOverlay.isNull() && document.getComponentOverlayOpacity() > 0.0f)
updateComponentOverlay();
if (componentOverlay.isValid())
{
const Rectangle<int> clip (getComponentArea());
g.drawImageAt (componentOverlay, clip.getX(), clip.getY());
}
}
void PaintRoutineEditor::resized()
{
if (getWidth() > 0 && getHeight() > 0)
{
componentOverlay = Image();
refreshAllElements();
}
}
void PaintRoutineEditor::updateChildBounds()
{
const Rectangle<int> clip (getComponentArea());
for (int i = 0; i < getNumChildComponents(); ++i)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
e->updateBounds (clip);
}
void PaintRoutineEditor::updateComponentOverlay()
{
if (componentOverlay.isValid())
repaint();
componentOverlay = Image();
componentOverlayOpacity = document.getComponentOverlayOpacity();
if (componentOverlayOpacity > 0.0f)
{
if (documentHolder != nullptr)
componentOverlay = documentHolder->createComponentLayerSnapshot();
if (componentOverlay.isValid())
{
componentOverlay.multiplyAllAlphas (componentOverlayOpacity);
repaint();
}
}
}
void PaintRoutineEditor::visibilityChanged()
{
document.beginTransaction();
if (isVisible())
{
refreshAllElements();
document.addChangeListener (this);
}
else
{
document.removeChangeListener (this);
componentOverlay = Image();
}
}
void PaintRoutineEditor::refreshAllElements()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (auto* e = dynamic_cast<PaintElement*> (getChildComponent (i)))
if (! graphics.containsElement (e))
removeChildComponent (e);
Component* last = nullptr;
for (int i = graphics.getNumElements(); --i >= 0;)
{
auto* e = graphics.getElement (i);
addAndMakeVisible (e);
if (last != nullptr)
e->toBehind (last);
else
e->toFront (false);
last = e;
}
updateChildBounds();
if (grid.updateFromDesign (document))
repaint();
if (currentBackgroundColour != graphics.getBackgroundColour())
{
currentBackgroundColour = graphics.getBackgroundColour();
repaint();
}
if (componentOverlayOpacity != document.getComponentOverlayOpacity())
{
componentOverlay = Image();
componentOverlayOpacity = document.getComponentOverlayOpacity();
repaint();
}
}
void PaintRoutineEditor::changeListenerCallback (ChangeBroadcaster*)
{
refreshAllElements();
}
void PaintRoutineEditor::mouseDown (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
ApplicationCommandManager* commandManager = &ProjucerApplication::getCommandManager();
PopupMenu m;
m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
m.addSeparator();
for (int i = 0; i < ObjectTypes::numElementTypes; ++i)
m.addCommandItem (commandManager, JucerCommandIDs::newElementBase + i);
m.showMenuAsync (PopupMenu::Options());
}
else
{
addChildComponent (lassoComp);
lassoComp.beginLasso (e, this);
}
}
void PaintRoutineEditor::mouseDrag (const MouseEvent& e)
{
lassoComp.toFront (false);
lassoComp.dragLasso (e);
}
void PaintRoutineEditor::mouseUp (const MouseEvent& e)
{
lassoComp.endLasso();
if (! (e.mouseWasDraggedSinceMouseDown() || e.mods.isAnyModifierKeyDown()))
{
graphics.getSelectedElements().deselectAll();
graphics.getSelectedPoints().deselectAll();
}
}
void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso)
{
for (int i = 0; i < getNumChildComponents(); ++i)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
if (e->getBounds().expanded (-e->borderThickness).intersects (lasso))
results.add (e);
}
SelectedItemSet <PaintElement*>& PaintRoutineEditor::getLassoSelection()
{
return graphics.getSelectedElements();
}
bool PaintRoutineEditor::isInterestedInFileDrag (const StringArray& files)
{
return File::createFileWithoutCheckingPath (files[0])
.hasFileExtension ("jpg;jpeg;png;gif;svg");
}
void PaintRoutineEditor::filesDropped (const StringArray& filenames, int x, int y)
{
const File f (filenames [0]);
if (f.existsAsFile())
{
std::unique_ptr<Drawable> d (Drawable::createFromImageFile (f));
if (d != nullptr)
{
d.reset();
document.beginTransaction();
graphics.dropImageAt (f,
jlimit (10, getWidth() - 10, x),
jlimit (10, getHeight() - 10, y));
document.beginTransaction();
}
}
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../Application/jucer_Application.h"
#include "../UI/jucer_JucerCommandIDs.h"
#include "jucer_PaintRoutineEditor.h"
#include "../jucer_ObjectTypes.h"
#include "jucer_JucerDocumentEditor.h"
//==============================================================================
PaintRoutineEditor::PaintRoutineEditor (PaintRoutine& pr, JucerDocument& doc,
JucerDocumentEditor* docHolder)
: graphics (pr),
document (doc),
documentHolder (docHolder),
componentOverlay (nullptr),
componentOverlayOpacity (0.0f)
{
refreshAllElements();
setSize (document.getInitialWidth(),
document.getInitialHeight());
}
PaintRoutineEditor::~PaintRoutineEditor()
{
document.removeChangeListener (this);
removeAllElementComps();
removeChildComponent (&lassoComp);
deleteAllChildren();
}
void PaintRoutineEditor::removeAllElementComps()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
removeChildComponent (e);
}
Rectangle<int> PaintRoutineEditor::getComponentArea() const
{
if (document.isFixedSize())
return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2,
(getHeight() - document.getInitialHeight()) / 2,
document.getInitialWidth(),
document.getInitialHeight());
return getLocalBounds().reduced (4);
}
//==============================================================================
void PaintRoutineEditor::paint (Graphics& g)
{
const Rectangle<int> clip (getComponentArea());
g.reduceClipRegion (clip);
g.setOrigin (clip.getPosition());
graphics.fillWithBackground (g, true);
grid.draw (g, &graphics);
}
void PaintRoutineEditor::paintOverChildren (Graphics& g)
{
if (componentOverlay.isNull() && document.getComponentOverlayOpacity() > 0.0f)
updateComponentOverlay();
if (componentOverlay.isValid())
{
const Rectangle<int> clip (getComponentArea());
g.drawImageAt (componentOverlay, clip.getX(), clip.getY());
}
}
void PaintRoutineEditor::resized()
{
if (getWidth() > 0 && getHeight() > 0)
{
componentOverlay = Image();
refreshAllElements();
}
}
void PaintRoutineEditor::updateChildBounds()
{
const Rectangle<int> clip (getComponentArea());
for (int i = 0; i < getNumChildComponents(); ++i)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
e->updateBounds (clip);
}
void PaintRoutineEditor::updateComponentOverlay()
{
if (componentOverlay.isValid())
repaint();
componentOverlay = Image();
componentOverlayOpacity = document.getComponentOverlayOpacity();
if (componentOverlayOpacity > 0.0f)
{
if (documentHolder != nullptr)
componentOverlay = documentHolder->createComponentLayerSnapshot();
if (componentOverlay.isValid())
{
componentOverlay.multiplyAllAlphas (componentOverlayOpacity);
repaint();
}
}
}
void PaintRoutineEditor::visibilityChanged()
{
document.beginTransaction();
if (isVisible())
{
refreshAllElements();
document.addChangeListener (this);
}
else
{
document.removeChangeListener (this);
componentOverlay = Image();
}
}
void PaintRoutineEditor::refreshAllElements()
{
for (int i = getNumChildComponents(); --i >= 0;)
if (auto* e = dynamic_cast<PaintElement*> (getChildComponent (i)))
if (! graphics.containsElement (e))
removeChildComponent (e);
Component* last = nullptr;
for (int i = graphics.getNumElements(); --i >= 0;)
{
auto* e = graphics.getElement (i);
addAndMakeVisible (e);
if (last != nullptr)
e->toBehind (last);
else
e->toFront (false);
last = e;
}
updateChildBounds();
if (grid.updateFromDesign (document))
repaint();
if (currentBackgroundColour != graphics.getBackgroundColour())
{
currentBackgroundColour = graphics.getBackgroundColour();
repaint();
}
if (componentOverlayOpacity != document.getComponentOverlayOpacity())
{
componentOverlay = Image();
componentOverlayOpacity = document.getComponentOverlayOpacity();
repaint();
}
}
void PaintRoutineEditor::changeListenerCallback (ChangeBroadcaster*)
{
refreshAllElements();
}
void PaintRoutineEditor::mouseDown (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
ApplicationCommandManager* commandManager = &ProjucerApplication::getCommandManager();
PopupMenu m;
m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
m.addSeparator();
for (int i = 0; i < ObjectTypes::numElementTypes; ++i)
m.addCommandItem (commandManager, JucerCommandIDs::newElementBase + i);
m.showMenuAsync (PopupMenu::Options());
}
else
{
addChildComponent (lassoComp);
lassoComp.beginLasso (e, this);
}
}
void PaintRoutineEditor::mouseDrag (const MouseEvent& e)
{
lassoComp.toFront (false);
lassoComp.dragLasso (e);
}
void PaintRoutineEditor::mouseUp (const MouseEvent& e)
{
lassoComp.endLasso();
if (! (e.mouseWasDraggedSinceMouseDown() || e.mods.isAnyModifierKeyDown()))
{
graphics.getSelectedElements().deselectAll();
graphics.getSelectedPoints().deselectAll();
}
}
void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso)
{
for (int i = 0; i < getNumChildComponents(); ++i)
if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
if (e->getBounds().expanded (-e->borderThickness).intersects (lasso))
results.add (e);
}
SelectedItemSet <PaintElement*>& PaintRoutineEditor::getLassoSelection()
{
return graphics.getSelectedElements();
}
bool PaintRoutineEditor::isInterestedInFileDrag (const StringArray& files)
{
return File::createFileWithoutCheckingPath (files[0])
.hasFileExtension ("jpg;jpeg;png;gif;svg");
}
void PaintRoutineEditor::filesDropped (const StringArray& filenames, int x, int y)
{
const File f (filenames [0]);
if (f.existsAsFile())
{
std::unique_ptr<Drawable> d (Drawable::createFromImageFile (f));
if (d != nullptr)
{
d.reset();
document.beginTransaction();
graphics.dropImageAt (f,
jlimit (10, getWidth() - 10, x),
jlimit (10, getHeight() - 10, y));
document.beginTransaction();
}
}
}

View File

@ -1,83 +1,83 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "../jucer_PaintRoutine.h"
#include "jucer_SnapGridPainter.h"
class JucerDocumentEditor;
//==============================================================================
class PaintRoutineEditor : public Component,
public LassoSource <PaintElement*>,
public FileDragAndDropTarget,
private ChangeListener
{
public:
//==============================================================================
PaintRoutineEditor (PaintRoutine& graphics,
JucerDocument& document,
JucerDocumentEditor* const docHolder);
~PaintRoutineEditor();
//==============================================================================
void paint (Graphics& g);
void paintOverChildren (Graphics& g);
void resized();
void changeListenerCallback (ChangeBroadcaster*);
void mouseDown (const MouseEvent& e);
void mouseDrag (const MouseEvent& e);
void mouseUp (const MouseEvent& e);
void visibilityChanged();
void findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& area);
SelectedItemSet <PaintElement*>& getLassoSelection();
bool isInterestedInFileDrag (const StringArray& files);
void filesDropped (const StringArray& filenames, int x, int y);
Rectangle<int> getComponentArea() const;
//==============================================================================
void refreshAllElements();
private:
PaintRoutine& graphics;
JucerDocument& document;
JucerDocumentEditor* const documentHolder;
LassoComponent <PaintElement*> lassoComp;
SnapGridPainter grid;
Image componentOverlay;
float componentOverlayOpacity;
Colour currentBackgroundColour;
void removeAllElementComps();
void updateComponentOverlay();
void updateChildBounds();
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "../jucer_PaintRoutine.h"
#include "jucer_SnapGridPainter.h"
class JucerDocumentEditor;
//==============================================================================
class PaintRoutineEditor : public Component,
public LassoSource <PaintElement*>,
public FileDragAndDropTarget,
private ChangeListener
{
public:
//==============================================================================
PaintRoutineEditor (PaintRoutine& graphics,
JucerDocument& document,
JucerDocumentEditor* const docHolder);
~PaintRoutineEditor();
//==============================================================================
void paint (Graphics& g);
void paintOverChildren (Graphics& g);
void resized();
void changeListenerCallback (ChangeBroadcaster*);
void mouseDown (const MouseEvent& e);
void mouseDrag (const MouseEvent& e);
void mouseUp (const MouseEvent& e);
void visibilityChanged();
void findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& area);
SelectedItemSet <PaintElement*>& getLassoSelection();
bool isInterestedInFileDrag (const StringArray& files);
void filesDropped (const StringArray& filenames, int x, int y);
Rectangle<int> getComponentArea() const;
//==============================================================================
void refreshAllElements();
private:
PaintRoutine& graphics;
JucerDocument& document;
JucerDocumentEditor* const documentHolder;
LassoComponent <PaintElement*> lassoComp;
SnapGridPainter grid;
Image componentOverlay;
float componentOverlayOpacity;
Colour currentBackgroundColour;
void removeAllElementComps();
void updateComponentOverlay();
void updateChildBounds();
};

View File

@ -1,185 +1,185 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_PaintRoutinePanel.h"
#include "../Properties/jucer_ColourPropertyComponent.h"
#include "../PaintElements/jucer_PaintElementPath.h"
//==============================================================================
class ComponentBackgroundColourProperty : public JucerColourPropertyComponent,
private ChangeListener
{
public:
ComponentBackgroundColourProperty (JucerDocument& doc,
PaintRoutine& routine_)
: JucerColourPropertyComponent ("background", false),
document (doc),
routine (routine_)
{
document.addChangeListener (this);
}
~ComponentBackgroundColourProperty() override
{
document.removeChangeListener (this);
}
void changeListenerCallback (ChangeBroadcaster*) override
{
refresh();
}
void setColour (Colour newColour) override { routine.setBackgroundColour (newColour); }
Colour getColour() const override { return routine.getBackgroundColour(); }
void resetToDefault() override
{
jassertfalse; // option shouldn't be visible
}
protected:
JucerDocument& document;
PaintRoutine& routine;
};
//==============================================================================
class GraphicsPropsPanel : public Component,
private ChangeListener
{
public:
GraphicsPropsPanel (PaintRoutine& paintRoutine_,
JucerDocument* doc)
: paintRoutine (paintRoutine_),
document (doc)
{
paintRoutine.getSelectedElements().addChangeListener (this);
paintRoutine.getSelectedPoints().addChangeListener (this);
addAndMakeVisible (propsPanel = new PropertyPanel());
}
~GraphicsPropsPanel() override
{
paintRoutine.getSelectedPoints().removeChangeListener (this);
paintRoutine.getSelectedElements().removeChangeListener (this);
clear();
deleteAllChildren();
}
void resized() override
{
propsPanel->setBounds (4, 4, getWidth() - 8, getHeight() - 8);
}
void clear()
{
propsPanel->clear();
}
void updateList()
{
auto state = propsPanel->getOpennessState();
clear();
if (document != nullptr)
{
Array <PropertyComponent*> props;
props.add (new ComponentBackgroundColourProperty (*document, paintRoutine));
propsPanel->addSection ("Class Properties", props);
}
if (state != nullptr)
propsPanel->restoreOpennessState (*state);
auto numSelected = paintRoutine.getSelectedElements().getNumSelected();
if (numSelected > 0) // xxx need to cope with multiple
{
if (auto* pe = paintRoutine.getSelectedElements().getSelectedItem (0))
{
if (paintRoutine.containsElement (pe))
{
Array <PropertyComponent*> props;
pe->getEditableProperties (props, numSelected > 1);
propsPanel->addSection (pe->getTypeName(), props);
}
}
}
if (paintRoutine.getSelectedPoints().getNumSelected() == 1) // xxx need to cope with multiple
{
if (auto* point = paintRoutine.getSelectedPoints().getSelectedItem (0))
{
Array <PropertyComponent*> props;
point->getEditableProperties (props, false);
propsPanel->addSection ("Path segment", props);
}
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
updateList();
}
PaintRoutine& paintRoutine;
JucerDocument* document;
PropertyPanel* propsPanel;
};
//==============================================================================
PaintRoutinePanel::PaintRoutinePanel (JucerDocument& doc, PaintRoutine& pr,
JucerDocumentEditor* documentHolder)
: EditingPanelBase (doc,
new GraphicsPropsPanel (pr, &doc),
new PaintRoutineEditor (pr, doc, documentHolder)),
routine (pr)
{
}
PaintRoutinePanel::~PaintRoutinePanel()
{
deleteAllChildren();
}
void PaintRoutinePanel::updatePropertiesList()
{
((GraphicsPropsPanel*) propsPanel)->updateList();
}
Rectangle<int> PaintRoutinePanel::getComponentArea() const
{
return ((PaintRoutineEditor*) editor)->getComponentArea();
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_PaintRoutinePanel.h"
#include "../Properties/jucer_ColourPropertyComponent.h"
#include "../PaintElements/jucer_PaintElementPath.h"
//==============================================================================
class ComponentBackgroundColourProperty : public JucerColourPropertyComponent,
private ChangeListener
{
public:
ComponentBackgroundColourProperty (JucerDocument& doc,
PaintRoutine& routine_)
: JucerColourPropertyComponent ("background", false),
document (doc),
routine (routine_)
{
document.addChangeListener (this);
}
~ComponentBackgroundColourProperty() override
{
document.removeChangeListener (this);
}
void changeListenerCallback (ChangeBroadcaster*) override
{
refresh();
}
void setColour (Colour newColour) override { routine.setBackgroundColour (newColour); }
Colour getColour() const override { return routine.getBackgroundColour(); }
void resetToDefault() override
{
jassertfalse; // option shouldn't be visible
}
protected:
JucerDocument& document;
PaintRoutine& routine;
};
//==============================================================================
class GraphicsPropsPanel : public Component,
private ChangeListener
{
public:
GraphicsPropsPanel (PaintRoutine& paintRoutine_,
JucerDocument* doc)
: paintRoutine (paintRoutine_),
document (doc)
{
paintRoutine.getSelectedElements().addChangeListener (this);
paintRoutine.getSelectedPoints().addChangeListener (this);
addAndMakeVisible (propsPanel = new PropertyPanel());
}
~GraphicsPropsPanel() override
{
paintRoutine.getSelectedPoints().removeChangeListener (this);
paintRoutine.getSelectedElements().removeChangeListener (this);
clear();
deleteAllChildren();
}
void resized() override
{
propsPanel->setBounds (4, 4, getWidth() - 8, getHeight() - 8);
}
void clear()
{
propsPanel->clear();
}
void updateList()
{
auto state = propsPanel->getOpennessState();
clear();
if (document != nullptr)
{
Array <PropertyComponent*> props;
props.add (new ComponentBackgroundColourProperty (*document, paintRoutine));
propsPanel->addSection ("Class Properties", props);
}
if (state != nullptr)
propsPanel->restoreOpennessState (*state);
auto numSelected = paintRoutine.getSelectedElements().getNumSelected();
if (numSelected > 0) // xxx need to cope with multiple
{
if (auto* pe = paintRoutine.getSelectedElements().getSelectedItem (0))
{
if (paintRoutine.containsElement (pe))
{
Array <PropertyComponent*> props;
pe->getEditableProperties (props, numSelected > 1);
propsPanel->addSection (pe->getTypeName(), props);
}
}
}
if (paintRoutine.getSelectedPoints().getNumSelected() == 1) // xxx need to cope with multiple
{
if (auto* point = paintRoutine.getSelectedPoints().getSelectedItem (0))
{
Array <PropertyComponent*> props;
point->getEditableProperties (props, false);
propsPanel->addSection ("Path segment", props);
}
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
updateList();
}
PaintRoutine& paintRoutine;
JucerDocument* document;
PropertyPanel* propsPanel;
};
//==============================================================================
PaintRoutinePanel::PaintRoutinePanel (JucerDocument& doc, PaintRoutine& pr,
JucerDocumentEditor* documentHolder)
: EditingPanelBase (doc,
new GraphicsPropsPanel (pr, &doc),
new PaintRoutineEditor (pr, doc, documentHolder)),
routine (pr)
{
}
PaintRoutinePanel::~PaintRoutinePanel()
{
deleteAllChildren();
}
void PaintRoutinePanel::updatePropertiesList()
{
((GraphicsPropsPanel*) propsPanel)->updateList();
}
Rectangle<int> PaintRoutinePanel::getComponentArea() const
{
return ((PaintRoutineEditor*) editor)->getComponentArea();
}

View File

@ -1,45 +1,45 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_PaintRoutineEditor.h"
#include "jucer_EditingPanelBase.h"
//==============================================================================
class PaintRoutinePanel : public EditingPanelBase
{
public:
PaintRoutinePanel (JucerDocument&, PaintRoutine&, JucerDocumentEditor*);
~PaintRoutinePanel();
PaintRoutine& getPaintRoutine() const noexcept { return routine; }
void updatePropertiesList();
Rectangle<int> getComponentArea() const;
private:
PaintRoutine& routine;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "jucer_PaintRoutineEditor.h"
#include "jucer_EditingPanelBase.h"
//==============================================================================
class PaintRoutinePanel : public EditingPanelBase
{
public:
PaintRoutinePanel (JucerDocument&, PaintRoutine&, JucerDocumentEditor*);
~PaintRoutinePanel();
PaintRoutine& getPaintRoutine() const noexcept { return routine; }
void updatePropertiesList();
Rectangle<int> getComponentArea() const;
private:
PaintRoutine& routine;
};

View File

@ -1,272 +1,272 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_ResourceEditorPanel.h"
//==============================================================================
class ResourceListButton : public Component
{
public:
explicit ResourceListButton (JucerDocument& doc)
: document (doc), reloadButton ("Reload"), row (0)
{
setInterceptsMouseClicks (false, true);
addAndMakeVisible (reloadButton);
reloadButton.onClick = [this]
{
if (auto* r = document.getResources() [row])
document.getResources().browseForResource ("Select a file to replace this resource", "*",
File (r->originalFilename), r->name, nullptr);
};
}
void update (int newRow)
{
row = newRow;
reloadButton.setVisible (document.getResources() [row] != nullptr);
}
void resized()
{
reloadButton.setBoundsInset (BorderSize<int> (2));
}
private:
JucerDocument& document;
TextButton reloadButton;
int row;
};
//==============================================================================
ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc)
: document (doc),
addButton ("Add new resource..."),
reloadAllButton ("Reload all resources"),
delButton ("Delete selected resources")
{
addAndMakeVisible (addButton);
addButton.onClick = [this]
{
document.getResources().browseForResource ("Select a file to add as a resource", "*", {}, {}, nullptr);
};
addAndMakeVisible (reloadAllButton);
reloadAllButton.onClick = [this] { reloadAll(); };
addAndMakeVisible (delButton);
delButton.setEnabled (false);
delButton.onClick = [this] { document.getResources().remove (listBox->getSelectedRow (0)); };
listBox.reset (new TableListBox (String(), this));
addAndMakeVisible (listBox.get());
listBox->getHeader().addColumn ("name", 1, 150, 80, 400);
listBox->getHeader().addColumn ("original file", 2, 350, 80, 800);
listBox->getHeader().addColumn ("size", 3, 100, 40, 150);
listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable);
listBox->getHeader().setStretchToFitActive (true);
listBox->setOutlineThickness (1);
listBox->updateContent();
document.addChangeListener (this);
handleCommandMessage (1);
lookAndFeelChanged();
}
ResourceEditorPanel::~ResourceEditorPanel()
{
document.removeChangeListener (this);
}
int ResourceEditorPanel::getNumRows()
{
return document.getResources().size();
}
void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/,
int /*width*/, int /*height*/, bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (findColour (defaultHighlightColourId));
}
void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height,
bool rowIsSelected)
{
if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber])
{
String text;
if (columnId == 1)
text = r->name;
else if (columnId == 2)
text = r->originalFilename;
else if (columnId == 3)
text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
if (rowIsSelected)
g.setColour (findColour (defaultHighlightedTextColourId));
else
g.setColour (findColour (defaultTextColourId));
g.setFont (13.0f);
g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true);
}
}
Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
Component* existingComponentToUpdate)
{
if (columnId != 4)
return nullptr;
if (existingComponentToUpdate == nullptr)
existingComponentToUpdate = new ResourceListButton (document);
((ResourceListButton*) existingComponentToUpdate)->update (rowNumber);
return existingComponentToUpdate;
}
int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId)
{
if (columnId == 4)
return 0;
Font f (13.0f);
int widest = 40;
for (int i = document.getResources().size(); --i >= 0;)
{
const BinaryResources::BinaryResource* const r = document.getResources() [i];
jassert (r != nullptr);
String text;
if (columnId == 1)
text = r->name;
else if (columnId == 2)
text = r->originalFilename;
else if (columnId == 3)
text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
widest = jmax (widest, f.getStringWidth (text));
}
return widest + 10;
}
void ResourceEditorPanel::lookAndFeelChanged()
{
listBox->setColour (ListBox::backgroundColourId, findColour (secondaryBackgroundColourId));
listBox->setColour (ListBox::outlineColourId, Colours::transparentBlack);
}
//==============================================================================
class ResourceSorter
{
public:
ResourceSorter (const int columnId_, const bool forwards)
: columnId (columnId_),
direction (forwards ? 1 : -1)
{
}
int compareElements (BinaryResources::BinaryResource* first, BinaryResources::BinaryResource* second)
{
if (columnId == 1) return direction * first->name.compare (second->name);
if (columnId == 2) return direction * first->originalFilename.compare (second->originalFilename);
if (columnId == 3) return direction * (int) first->data.getSize() - (int) second->data.getSize();
return 0;
}
private:
const int columnId, direction;
ResourceSorter (const ResourceSorter&);
ResourceSorter& operator= (const ResourceSorter&);
};
void ResourceEditorPanel::sortOrderChanged (int newSortColumnId, const bool isForwards)
{
ResourceSorter sorter (newSortColumnId, isForwards);
document.getResources().sort (sorter);
}
//==============================================================================
void ResourceEditorPanel::selectedRowsChanged (int /*lastRowSelected*/)
{
delButton.setEnabled (listBox->getNumSelectedRows() > 0);
}
void ResourceEditorPanel::resized()
{
auto bounds = getLocalBounds();
auto buttonSlice = bounds.removeFromBottom (40).reduced (5, 5);
addButton.setBounds (buttonSlice.removeFromLeft (125));
buttonSlice.removeFromLeft (10);
reloadAllButton.setBounds (buttonSlice.removeFromLeft (125));
delButton.setBounds (buttonSlice.removeFromRight (125));
listBox->setBounds (bounds);
}
void ResourceEditorPanel::paint (Graphics& g)
{
g.fillAll (findColour (secondaryBackgroundColourId));
}
void ResourceEditorPanel::visibilityChanged()
{
if (isVisible())
listBox->updateContent();
}
void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*)
{
if (isVisible())
listBox->updateContent();
}
void ResourceEditorPanel::reloadAll()
{
StringArray failed;
for (int i = 0; i < document.getResources().size(); ++i)
if (! document.getResources().reload (i))
failed.add (document.getResources().getResourceNames() [i]);
if (failed.size() > 0)
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
TRANS("Reloading resources"),
TRANS("The following resources couldn't be reloaded from their original files:\n\n")
+ failed.joinIntoString (", "));
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_ResourceEditorPanel.h"
//==============================================================================
class ResourceListButton : public Component
{
public:
explicit ResourceListButton (JucerDocument& doc)
: document (doc), reloadButton ("Reload"), row (0)
{
setInterceptsMouseClicks (false, true);
addAndMakeVisible (reloadButton);
reloadButton.onClick = [this]
{
if (auto* r = document.getResources() [row])
document.getResources().browseForResource ("Select a file to replace this resource", "*",
File (r->originalFilename), r->name, nullptr);
};
}
void update (int newRow)
{
row = newRow;
reloadButton.setVisible (document.getResources() [row] != nullptr);
}
void resized()
{
reloadButton.setBoundsInset (BorderSize<int> (2));
}
private:
JucerDocument& document;
TextButton reloadButton;
int row;
};
//==============================================================================
ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc)
: document (doc),
addButton ("Add new resource..."),
reloadAllButton ("Reload all resources"),
delButton ("Delete selected resources")
{
addAndMakeVisible (addButton);
addButton.onClick = [this]
{
document.getResources().browseForResource ("Select a file to add as a resource", "*", {}, {}, nullptr);
};
addAndMakeVisible (reloadAllButton);
reloadAllButton.onClick = [this] { reloadAll(); };
addAndMakeVisible (delButton);
delButton.setEnabled (false);
delButton.onClick = [this] { document.getResources().remove (listBox->getSelectedRow (0)); };
listBox.reset (new TableListBox (String(), this));
addAndMakeVisible (listBox.get());
listBox->getHeader().addColumn ("name", 1, 150, 80, 400);
listBox->getHeader().addColumn ("original file", 2, 350, 80, 800);
listBox->getHeader().addColumn ("size", 3, 100, 40, 150);
listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable);
listBox->getHeader().setStretchToFitActive (true);
listBox->setOutlineThickness (1);
listBox->updateContent();
document.addChangeListener (this);
handleCommandMessage (1);
lookAndFeelChanged();
}
ResourceEditorPanel::~ResourceEditorPanel()
{
document.removeChangeListener (this);
}
int ResourceEditorPanel::getNumRows()
{
return document.getResources().size();
}
void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/,
int /*width*/, int /*height*/, bool rowIsSelected)
{
if (rowIsSelected)
g.fillAll (findColour (defaultHighlightColourId));
}
void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height,
bool rowIsSelected)
{
if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber])
{
String text;
if (columnId == 1)
text = r->name;
else if (columnId == 2)
text = r->originalFilename;
else if (columnId == 3)
text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
if (rowIsSelected)
g.setColour (findColour (defaultHighlightedTextColourId));
else
g.setColour (findColour (defaultTextColourId));
g.setFont (13.0f);
g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true);
}
}
Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
Component* existingComponentToUpdate)
{
if (columnId != 4)
return nullptr;
if (existingComponentToUpdate == nullptr)
existingComponentToUpdate = new ResourceListButton (document);
((ResourceListButton*) existingComponentToUpdate)->update (rowNumber);
return existingComponentToUpdate;
}
int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId)
{
if (columnId == 4)
return 0;
Font f (13.0f);
int widest = 40;
for (int i = document.getResources().size(); --i >= 0;)
{
const BinaryResources::BinaryResource* const r = document.getResources() [i];
jassert (r != nullptr);
String text;
if (columnId == 1)
text = r->name;
else if (columnId == 2)
text = r->originalFilename;
else if (columnId == 3)
text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
widest = jmax (widest, f.getStringWidth (text));
}
return widest + 10;
}
void ResourceEditorPanel::lookAndFeelChanged()
{
listBox->setColour (ListBox::backgroundColourId, findColour (secondaryBackgroundColourId));
listBox->setColour (ListBox::outlineColourId, Colours::transparentBlack);
}
//==============================================================================
class ResourceSorter
{
public:
ResourceSorter (const int columnId_, const bool forwards)
: columnId (columnId_),
direction (forwards ? 1 : -1)
{
}
int compareElements (BinaryResources::BinaryResource* first, BinaryResources::BinaryResource* second)
{
if (columnId == 1) return direction * first->name.compare (second->name);
if (columnId == 2) return direction * first->originalFilename.compare (second->originalFilename);
if (columnId == 3) return direction * (int) first->data.getSize() - (int) second->data.getSize();
return 0;
}
private:
const int columnId, direction;
ResourceSorter (const ResourceSorter&);
ResourceSorter& operator= (const ResourceSorter&);
};
void ResourceEditorPanel::sortOrderChanged (int newSortColumnId, const bool isForwards)
{
ResourceSorter sorter (newSortColumnId, isForwards);
document.getResources().sort (sorter);
}
//==============================================================================
void ResourceEditorPanel::selectedRowsChanged (int /*lastRowSelected*/)
{
delButton.setEnabled (listBox->getNumSelectedRows() > 0);
}
void ResourceEditorPanel::resized()
{
auto bounds = getLocalBounds();
auto buttonSlice = bounds.removeFromBottom (40).reduced (5, 5);
addButton.setBounds (buttonSlice.removeFromLeft (125));
buttonSlice.removeFromLeft (10);
reloadAllButton.setBounds (buttonSlice.removeFromLeft (125));
delButton.setBounds (buttonSlice.removeFromRight (125));
listBox->setBounds (bounds);
}
void ResourceEditorPanel::paint (Graphics& g)
{
g.fillAll (findColour (secondaryBackgroundColourId));
}
void ResourceEditorPanel::visibilityChanged()
{
if (isVisible())
listBox->updateContent();
}
void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*)
{
if (isVisible())
listBox->updateContent();
}
void ResourceEditorPanel::reloadAll()
{
StringArray failed;
for (int i = 0; i < document.getResources().size(); ++i)
if (! document.getResources().reload (i))
failed.add (document.getResources().getResourceNames() [i]);
if (failed.size() > 0)
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
TRANS("Reloading resources"),
TRANS("The following resources couldn't be reloaded from their original files:\n\n")
+ failed.joinIntoString (", "));
}

View File

@ -1,59 +1,59 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class ResourceEditorPanel : public Component,
private TableListBoxModel,
private ChangeListener
{
public:
ResourceEditorPanel (JucerDocument& document);
~ResourceEditorPanel() override;
void resized() override;
void paint (Graphics& g) override;
void visibilityChanged() override;
void changeListenerCallback (ChangeBroadcaster*) override;
int getNumRows() override;
void paintRowBackground (Graphics& g, int rowNumber, int width, int height, bool rowIsSelected) override;
void paintCell (Graphics& g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) override;
Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected, Component* existingComponentToUpdate) override;
int getColumnAutoSizeWidth (int columnId) override;
void sortOrderChanged (int newSortColumnId, bool isForwards) override;
void selectedRowsChanged (int lastRowSelected) override;
private:
void lookAndFeelChanged() override;
void reloadAll();
JucerDocument& document;
std::unique_ptr<TableListBox> listBox;
TextButton addButton, reloadAllButton, delButton;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class ResourceEditorPanel : public Component,
private TableListBoxModel,
private ChangeListener
{
public:
ResourceEditorPanel (JucerDocument& document);
~ResourceEditorPanel() override;
void resized() override;
void paint (Graphics& g) override;
void visibilityChanged() override;
void changeListenerCallback (ChangeBroadcaster*) override;
int getNumRows() override;
void paintRowBackground (Graphics& g, int rowNumber, int width, int height, bool rowIsSelected) override;
void paintCell (Graphics& g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) override;
Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected, Component* existingComponentToUpdate) override;
int getColumnAutoSizeWidth (int columnId) override;
void sortOrderChanged (int newSortColumnId, bool isForwards) override;
void selectedRowsChanged (int lastRowSelected) override;
private:
void lookAndFeelChanged() override;
void reloadAll();
JucerDocument& document;
std::unique_ptr<TableListBox> listBox;
TextButton addButton, reloadAllButton, delButton;
};

View File

@ -1,80 +1,80 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "../jucer_PaintRoutine.h"
//==============================================================================
class SnapGridPainter
{
public:
SnapGridPainter()
: snapGridSize (-1), snapShown (false)
{
}
bool updateFromDesign (JucerDocument& design)
{
if (snapGridSize != design.getSnappingGridSize()
|| snapShown != (design.isSnapShown() && design.isSnapActive (false)))
{
snapGridSize = design.getSnappingGridSize();
snapShown = design.isSnapShown() && design.isSnapActive (false);
return true;
}
return false;
}
void draw (Graphics& g, PaintRoutine* backgroundGraphics)
{
if (snapShown && snapGridSize > 2)
{
Colour col (Colours::black);
if (backgroundGraphics != nullptr)
col = backgroundGraphics->getBackgroundColour().contrasting();
const Rectangle<int> clip (g.getClipBounds());
RectangleList<float> gridLines;
for (int x = clip.getX() - (clip.getX() % snapGridSize); x < clip.getRight(); x += snapGridSize)
gridLines.addWithoutMerging (Rectangle<float> ((float) x, 0.0f, 1.0f, (float) clip.getBottom()));
for (int y = clip.getY() - (clip.getY() % snapGridSize); y < clip.getBottom(); y += snapGridSize)
gridLines.addWithoutMerging (Rectangle<float> (0.0f, (float) y, (float) clip.getRight(), 1.0f));
g.setColour (col.withAlpha (0.1f));
g.fillRectList (gridLines);
}
}
private:
int snapGridSize;
bool snapShown;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
#include "../jucer_PaintRoutine.h"
//==============================================================================
class SnapGridPainter
{
public:
SnapGridPainter()
: snapGridSize (-1), snapShown (false)
{
}
bool updateFromDesign (JucerDocument& design)
{
if (snapGridSize != design.getSnappingGridSize()
|| snapShown != (design.isSnapShown() && design.isSnapActive (false)))
{
snapGridSize = design.getSnappingGridSize();
snapShown = design.isSnapShown() && design.isSnapActive (false);
return true;
}
return false;
}
void draw (Graphics& g, PaintRoutine* backgroundGraphics)
{
if (snapShown && snapGridSize > 2)
{
Colour col (Colours::black);
if (backgroundGraphics != nullptr)
col = backgroundGraphics->getBackgroundColour().contrasting();
const Rectangle<int> clip (g.getClipBounds());
RectangleList<float> gridLines;
for (int x = clip.getX() - (clip.getX() % snapGridSize); x < clip.getRight(); x += snapGridSize)
gridLines.addWithoutMerging (Rectangle<float> ((float) x, 0.0f, 1.0f, (float) clip.getBottom()));
for (int y = clip.getY() - (clip.getY() % snapGridSize); y < clip.getBottom(); y += snapGridSize)
gridLines.addWithoutMerging (Rectangle<float> (0.0f, (float) y, (float) clip.getRight(), 1.0f));
g.setColour (col.withAlpha (0.1f));
g.fillRectList (gridLines);
}
}
private:
int snapGridSize;
bool snapShown;
};

View File

@ -1,179 +1,179 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_TestComponent.h"
#include "../jucer_ObjectTypes.h"
static Array <TestComponent*> testComponents;
//==============================================================================
TestComponent::TestComponent (JucerDocument* const doc,
JucerDocument* const loaded,
const bool alwaysFill)
: ownerDocument (doc),
loadedDocument (loaded),
alwaysFillBackground (alwaysFill)
{
setToInitialSize();
updateContents();
testComponents.add (this);
setLookAndFeel (&getLookAndFeel());
}
TestComponent::~TestComponent()
{
testComponents.removeFirstMatchingValue (this);
deleteAllChildren();
}
//==============================================================================
void TestComponent::reloadAll()
{
for (int i = testComponents.size(); --i >= 0;)
testComponents.getUnchecked(i)->reload();
}
void TestComponent::reload()
{
if (findFile().exists() && lastModificationTime != findFile().getLastModificationTime())
setFilename (filename);
}
//==============================================================================
static StringArray recursiveFiles;
File TestComponent::findFile() const
{
if (filename.isEmpty())
return {};
if (ownerDocument != nullptr)
return ownerDocument->getCppFile().getSiblingFile (filename);
return File::getCurrentWorkingDirectory().getChildFile (filename);
}
void TestComponent::setFilename (const String& newName)
{
File newFile;
if (newName.isNotEmpty())
{
if (ownerDocument != nullptr)
newFile = ownerDocument->getCppFile().getSiblingFile (newName);
else
newFile = File::getCurrentWorkingDirectory().getChildFile (newName);
}
if (! recursiveFiles.contains (newFile.getFullPathName()))
{
recursiveFiles.add (newFile.getFullPathName());
loadedDocument.reset();
filename = newName;
lastModificationTime = findFile().getLastModificationTime();
loadedDocument.reset (JucerDocument::createForCppFile (nullptr, findFile()));
updateContents();
repaint();
recursiveFiles.remove (recursiveFiles.size() - 1);
}
}
void TestComponent::setConstructorParams (const String& newParams)
{
constructorParams = newParams;
}
void TestComponent::updateContents()
{
deleteAllChildren();
repaint();
if (loadedDocument != nullptr)
{
addAndMakeVisible (loadedDocument->createTestComponent (alwaysFillBackground));
resized();
}
}
void TestComponent::setToInitialSize()
{
if (loadedDocument != nullptr)
setSize (loadedDocument->getInitialWidth(),
loadedDocument->getInitialHeight());
else
setSize (100, 100);
}
//==============================================================================
void TestComponent::paint (Graphics& g)
{
if (loadedDocument == nullptr)
{
g.fillAll (Colours::white.withAlpha (0.25f));
g.setColour (Colours::black.withAlpha (0.5f));
g.drawRect (getLocalBounds());
g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight());
g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f);
g.setFont (14.0f);
g.drawText ("Projucer Component",
0, 0, getWidth(), getHeight() / 2,
Justification::centred, true);
g.drawText ("(no file loaded)",
0, getHeight() / 2, getWidth(), getHeight() / 2,
Justification::centred, true);
}
}
void TestComponent::resized()
{
if (Component* const c = getChildComponent (0))
{
setOpaque (c->isOpaque());
c->setBounds (getLocalBounds());
}
}
//==============================================================================
void TestComponent::showInDialogBox (JucerDocument& document)
{
DialogWindow::LaunchOptions o;
o.content.setOwned (new TestComponent (nullptr, document.createCopy(), true));
o.dialogTitle = "Testing: " + document.getClassName();
o.dialogBackgroundColour = Colours::azure;
o.escapeKeyTriggersCloseButton = true;
o.useNativeTitleBar = false;
o.resizable = true;
o.launchAsync();
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_TestComponent.h"
#include "../jucer_ObjectTypes.h"
static Array <TestComponent*> testComponents;
//==============================================================================
TestComponent::TestComponent (JucerDocument* const doc,
JucerDocument* const loaded,
const bool alwaysFill)
: ownerDocument (doc),
loadedDocument (loaded),
alwaysFillBackground (alwaysFill)
{
setToInitialSize();
updateContents();
testComponents.add (this);
setLookAndFeel (&getLookAndFeel());
}
TestComponent::~TestComponent()
{
testComponents.removeFirstMatchingValue (this);
deleteAllChildren();
}
//==============================================================================
void TestComponent::reloadAll()
{
for (int i = testComponents.size(); --i >= 0;)
testComponents.getUnchecked(i)->reload();
}
void TestComponent::reload()
{
if (findFile().exists() && lastModificationTime != findFile().getLastModificationTime())
setFilename (filename);
}
//==============================================================================
static StringArray recursiveFiles;
File TestComponent::findFile() const
{
if (filename.isEmpty())
return {};
if (ownerDocument != nullptr)
return ownerDocument->getCppFile().getSiblingFile (filename);
return File::getCurrentWorkingDirectory().getChildFile (filename);
}
void TestComponent::setFilename (const String& newName)
{
File newFile;
if (newName.isNotEmpty())
{
if (ownerDocument != nullptr)
newFile = ownerDocument->getCppFile().getSiblingFile (newName);
else
newFile = File::getCurrentWorkingDirectory().getChildFile (newName);
}
if (! recursiveFiles.contains (newFile.getFullPathName()))
{
recursiveFiles.add (newFile.getFullPathName());
loadedDocument.reset();
filename = newName;
lastModificationTime = findFile().getLastModificationTime();
loadedDocument.reset (JucerDocument::createForCppFile (nullptr, findFile()));
updateContents();
repaint();
recursiveFiles.remove (recursiveFiles.size() - 1);
}
}
void TestComponent::setConstructorParams (const String& newParams)
{
constructorParams = newParams;
}
void TestComponent::updateContents()
{
deleteAllChildren();
repaint();
if (loadedDocument != nullptr)
{
addAndMakeVisible (loadedDocument->createTestComponent (alwaysFillBackground));
resized();
}
}
void TestComponent::setToInitialSize()
{
if (loadedDocument != nullptr)
setSize (loadedDocument->getInitialWidth(),
loadedDocument->getInitialHeight());
else
setSize (100, 100);
}
//==============================================================================
void TestComponent::paint (Graphics& g)
{
if (loadedDocument == nullptr)
{
g.fillAll (Colours::white.withAlpha (0.25f));
g.setColour (Colours::black.withAlpha (0.5f));
g.drawRect (getLocalBounds());
g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight());
g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f);
g.setFont (14.0f);
g.drawText ("Projucer Component",
0, 0, getWidth(), getHeight() / 2,
Justification::centred, true);
g.drawText ("(no file loaded)",
0, getHeight() / 2, getWidth(), getHeight() / 2,
Justification::centred, true);
}
}
void TestComponent::resized()
{
if (Component* const c = getChildComponent (0))
{
setOpaque (c->isOpaque());
c->setBounds (getLocalBounds());
}
}
//==============================================================================
void TestComponent::showInDialogBox (JucerDocument& document)
{
DialogWindow::LaunchOptions o;
o.content.setOwned (new TestComponent (nullptr, document.createCopy(), true));
o.dialogTitle = "Testing: " + document.getClassName();
o.dialogBackgroundColour = Colours::azure;
o.escapeKeyTriggersCloseButton = true;
o.useNativeTitleBar = false;
o.resizable = true;
o.launchAsync();
}

View File

@ -1,73 +1,73 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class TestComponent : public Component
{
public:
//==============================================================================
TestComponent (JucerDocument* const ownerDocument,
JucerDocument* const loadedDocument,
const bool alwaysFillBackground);
~TestComponent() override;
//==============================================================================
void setFilename (const String& fn);
const String& getFilename() const noexcept { return filename; }
void setConstructorParams (const String& newParams);
const String& getConstructorParams() const noexcept { return constructorParams; }
File findFile() const;
JucerDocument* getDocument() const noexcept { return loadedDocument.get(); }
JucerDocument* getOwnerDocument() const noexcept { return ownerDocument; }
void setToInitialSize();
//==============================================================================
void paint (Graphics&) override;
void resized() override;
static void showInDialogBox (JucerDocument&);
// reloads any test comps that need to do so
static void reloadAll();
private:
JucerDocument* ownerDocument;
std::unique_ptr<JucerDocument> loadedDocument;
String filename, constructorParams;
Time lastModificationTime;
const bool alwaysFillBackground;
void updateContents();
void reload();
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../jucer_JucerDocument.h"
//==============================================================================
class TestComponent : public Component
{
public:
//==============================================================================
TestComponent (JucerDocument* const ownerDocument,
JucerDocument* const loadedDocument,
const bool alwaysFillBackground);
~TestComponent() override;
//==============================================================================
void setFilename (const String& fn);
const String& getFilename() const noexcept { return filename; }
void setConstructorParams (const String& newParams);
const String& getConstructorParams() const noexcept { return constructorParams; }
File findFile() const;
JucerDocument* getDocument() const noexcept { return loadedDocument.get(); }
JucerDocument* getOwnerDocument() const noexcept { return ownerDocument; }
void setToInitialSize();
//==============================================================================
void paint (Graphics&) override;
void resized() override;
static void showInDialogBox (JucerDocument&);
// reloads any test comps that need to do so
static void reloadAll();
private:
JucerDocument* ownerDocument;
std::unique_ptr<JucerDocument> loadedDocument;
String filename, constructorParams;
Time lastModificationTime;
const bool alwaysFillBackground;
void updateContents();
void reload();
};