migrating to the latest JUCE version
This commit is contained in:
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 (", "));
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
Reference in New Issue
Block a user