Skip to content

Commit

Permalink
Merge pull request #96 from sudara/feature/setroot
Browse files Browse the repository at this point in the history
Feature/setroot
  • Loading branch information
sudara authored Jan 11, 2024
2 parents 3d9b8ad + e2b4598 commit a422fea
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 39 deletions.
19 changes: 15 additions & 4 deletions melatonin/components/fps_meter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ namespace melatonin
class FPSMeter : public juce::Component, private juce::Timer
{
public:
explicit FPSMeter (juce::Component& o) : overlay (o)
FPSMeter ()
{
overlay.addChildComponent (this);

// don't repaint the parent
// unfortunately, on macOS, this no longer works
// See FAQ in README for more info
Expand All @@ -26,6 +24,19 @@ namespace melatonin
setInterceptsMouseClicks (false, false);
}

void setRoot (juce::Component& o)
{
overlay = &o;

overlay->addChildComponent (this);
}

void clearRoot()
{
if (overlay)
overlay->removeChildComponent (this);
}

void timerCallback() override
{
TRACE_EVENT ("component", "fps timer callback");
Expand Down Expand Up @@ -108,7 +119,7 @@ namespace melatonin
}

private:
juce::Component& overlay;
juce::Component* overlay = nullptr;
juce::Rectangle<int> bounds;
juce::Font font = juce::Font (juce::Font::getDefaultMonospacedFontName(), 16.0f, juce::Font::plain);
double lastTime = juce::Time::getMillisecondCounterHiRes();
Expand Down
34 changes: 22 additions & 12 deletions melatonin/helpers/overlay_mouse_listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,42 @@ namespace melatonin
class OverlayMouseListener : public juce::MouseListener
{
public:
explicit OverlayMouseListener (juce::Component& c, bool startEnabled = true) : root (c)
OverlayMouseListener()
{
// Listen to all mouse movements for all children of the root
if (startEnabled)
{
enabled = true;
root.addMouseListener (this, true);
}
}

~OverlayMouseListener() override
{
if (enabled && root)
root->removeMouseListener (this);
}

void setRoot (juce::Component& c)
{
root = &c;

if (enabled)
root.removeMouseListener (this);
root->addMouseListener (this, true);
}

void clearRoot()
{
if (enabled && root)
root->removeMouseListener (this);

root = nullptr;
}

void enable()
{
enabled = true;
root.addMouseListener (this, true);
root->addMouseListener (this, true);
}

void disable()
{
enabled = false;
root.removeMouseListener (this);
root->removeMouseListener (this);
}

void mouseEnter (const juce::MouseEvent& event) override
Expand Down Expand Up @@ -78,7 +88,7 @@ namespace melatonin

void mouseExit (const juce::MouseEvent& event) override
{
if (event.originalComponent == &root)
if (event.originalComponent == root)
{
mouseExitCallback();
}
Expand All @@ -94,7 +104,7 @@ namespace melatonin
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OverlayMouseListener)

juce::Component& root;
juce::Component* root = nullptr;
bool enabled = false;
bool isDragging { false };
};
Expand Down
27 changes: 22 additions & 5 deletions melatonin/inspector_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace melatonin
class InspectorComponent : public juce::Component
{
public:
explicit InspectorComponent (juce::Component& rootComponent, bool enabledAtStart = true) : root (rootComponent), inspectorEnabled (enabledAtStart)
explicit InspectorComponent()
{
TRACE_COMPONENT();

Expand Down Expand Up @@ -48,7 +48,6 @@ namespace melatonin
addAndMakeVisible (searchIcon);
addChildComponent (clearButton);

colorPicker.setRootComponent (&root);
colorPicker.togglePickerCallback = [this] (bool value) {
if (toggleOverlayCallback)
{
Expand Down Expand Up @@ -153,6 +152,24 @@ namespace melatonin
tree.setRootItem (nullptr);
}

void setRoot (juce::Component& r)
{
root = &r;
colorPicker.setRootComponent (root);

tree.setRootItem (nullptr);
rootItem = nullptr;

if (inspectorEnabled)
ensureTreeIsConstructed();
}

void clearRoot()
{
root = nullptr;
colorPicker.setRootComponent (nullptr);
}

void paint (juce::Graphics& g) override
{
auto mainPanelGradient = juce::ColourGradient::horizontal (colors::panelBackgroundDarker, (float) mainColumnBounds.getX(), colors::panelBackgroundLighter, (float) mainColumnBounds.getWidth());
Expand Down Expand Up @@ -185,7 +202,7 @@ namespace melatonin
tree.setRootItem (nullptr);

// construct the root item
rootItem = std::make_unique<ComponentTreeViewItem> (&root, outlineComponentCallback, selectComponentCallback);
rootItem = std::make_unique<ComponentTreeViewItem> (root, outlineComponentCallback, selectComponentCallback);
tree.setRootItem (rootItem.get());
getRoot()->setOpenness (ComponentTreeViewItem::Openness::opennessOpen);

Expand Down Expand Up @@ -354,10 +371,10 @@ namespace melatonin

private:
Component::SafePointer<Component> selectedComponent;
Component& root;
Component* root = nullptr;
juce::SharedResourcePointer<InspectorSettings> settings;
ComponentModel model;
bool inspectorEnabled;
bool inspectorEnabled = false;

juce::Rectangle<int> mainColumnBounds, topArea, searchBoxBounds, treeViewBounds;
InspectorImageButton logo { "logo" };
Expand Down
98 changes: 80 additions & 18 deletions melatonin_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ END_JUCE_MODULE_DECLARATION

namespace melatonin
{
class Inspector : public juce::ComponentListener, public juce::DocumentWindow
class Inspector : public juce::ComponentListener, public juce::DocumentWindow, private juce::Timer
{
public:
class InspectorKeyCommands : public juce::KeyListener
Expand Down Expand Up @@ -65,21 +65,13 @@ namespace melatonin
}
};
explicit Inspector (juce::Component& rootComponent, bool inspectorEnabledAtStart = true)
: juce::DocumentWindow ("Melatonin Inspector", colors::background, 7, true),
inspectorComponent (rootComponent),
root (rootComponent)
: juce::DocumentWindow ("Melatonin Inspector", colors::background, 7, true)
{
TRACE_COMPONENT();
root.addChildComponent (overlay);
overlay.setBounds (root.getLocalBounds());
root.addComponentListener (this);

// allow us to open/close the inspector by key command
// bit sketchy because we're modifying the source app to accept key focus
root.addKeyListener (&keyListener);
root.setWantsKeyboardFocus (true);
this->addKeyListener (&keyListener);

setRoot (rootComponent);

// needs to come before the LNF
restoreBoundsIfNeeded();

Expand All @@ -98,15 +90,48 @@ namespace melatonin

~Inspector() override
{
root.removeKeyListener (&keyListener);
clearRoot();

this->removeKeyListener (&keyListener);
root.removeComponentListener (this);

// needed, otherwise removing look and feel will save bounds
settings->props.reset();
setLookAndFeel (nullptr);
}

void setRoot (juce::Component& rootComponent)
{
clearRoot();

root = &rootComponent;

root->addChildComponent (overlay);
overlay.setBounds (root->getLocalBounds());
root->addComponentListener (this);

// allow us to open/close the inspector by key command
// bit sketchy because we're modifying the source app to accept key focus
root->addKeyListener (&keyListener);
root->setWantsKeyboardFocus (true);

fpsMeter.setRoot (*root);
overlayMouseListener.setRoot (*root);
inspectorComponent.setRoot (*root);
}

void clearRoot()
{
if (root == nullptr)
return;

root->removeKeyListener (&keyListener);
root->removeComponentListener (this);

fpsMeter.clearRoot();
overlayMouseListener.clearRoot();
inspectorComponent.clearRoot();
}

void moved() override
{
TRACE_COMPONENT();
Expand Down Expand Up @@ -288,18 +313,29 @@ namespace melatonin
toggle (!inspectorEnabled);
}

void setRootFollowsComponentUnderMouse (bool follow)
{
rootFollowsComponentUnderMouse = follow;

if (rootFollowsComponentUnderMouse)
startTimerHz (25);
else
stopTimer();
}

std::function<void()> onClose;

private:
juce::SharedResourcePointer<InspectorSettings> settings;
melatonin::InspectorLookAndFeel inspectorLookAndFeel;
melatonin::InspectorComponent inspectorComponent;
juce::Component& root;
juce::Component::SafePointer<juce::Component> root;
bool inspectorEnabled = false;
melatonin::Overlay overlay;
melatonin::FPSMeter fpsMeter { root };
melatonin::OverlayMouseListener overlayMouseListener { root, false };
melatonin::FPSMeter fpsMeter;
melatonin::OverlayMouseListener overlayMouseListener;
InspectorKeyCommands keyListener { *this };
bool rootFollowsComponentUnderMouse = false;

// Resize our overlay when the root component changes
void componentMovedOrResized (Component& rootComponent, bool wasMoved, bool wasResized) override
Expand All @@ -310,6 +346,32 @@ namespace melatonin
}
}

void componentBeingDeleted (juce::Component& component) override
{
if (&component == root)
{
clearRoot();

auto& d = juce::Desktop::getInstance();
for (int i = 0; i < d.getNumComponents(); i++)
{
if (auto c = d.getComponent (i); c != nullptr && c != this)
{
setRoot (*c);
return;
}
}
}
}

void timerCallback() override
{
for (auto ms : juce::Desktop::getInstance().getMouseSources())
if (auto c = ms.getComponentUnderMouse())
if (auto top = c->getTopLevelComponent(); top != nullptr && top != root && top != this)
setRoot (*top);
}

void setupCallbacks()
{
overlayMouseListener.outlineComponentCallback = [this] (Component* c) { this->outlineComponent (c); };
Expand All @@ -328,7 +390,7 @@ namespace melatonin
};
inspectorComponent.toggleFPSCallback = [this] (bool enable) {
if (enable)
this->fpsMeter.setBounds (root.getLocalBounds().removeFromRight (60).removeFromTop (40));
this->fpsMeter.setBounds (root->getLocalBounds().removeFromRight (60).removeFromTop (40));
this->fpsMeter.setVisible (enable);
};
}
Expand Down

0 comments on commit a422fea

Please sign in to comment.