From 727bb94818da4287012743a75a7cf7b2d15ef065 Mon Sep 17 00:00:00 2001 From: Daniel Walz Date: Tue, 10 Nov 2020 23:57:29 +0100 Subject: [PATCH 1/4] Implemented margin and padding with different values on each edge --- Layout/foleys_BoxModel.h | 101 ++++++++++++++++++++++++++++++++++++ Layout/foleys_Decorator.cpp | 22 ++++---- Layout/foleys_Decorator.h | 4 +- VERSION.md | 5 ++ foleys_gui_magic.h | 1 + 5 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 Layout/foleys_BoxModel.h diff --git a/Layout/foleys_BoxModel.h b/Layout/foleys_BoxModel.h new file mode 100644 index 00000000..13e84fc2 --- /dev/null +++ b/Layout/foleys_BoxModel.h @@ -0,0 +1,101 @@ +/* + ============================================================================== + Copyright (c) 2019-2020 Foleys Finest Audio Ltd. - Daniel Walz + All rights reserved. + + License for non-commercial projects: + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + License for commercial products: + + To sell commercial products containing this module, you are required to buy a + License from https://foleysfinest.com/developer/pluginguimagic/ + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + ============================================================================== + */ + +#pragma once + +namespace foleys +{ + +template +struct Box +{ + T top = {}; + T left = {}; + T right = {}; + T bottom = {}; + + Box() = default; + Box (T value) : top (value), left (value), right (value), bottom (value) {} + + static Box fromString (const juce::String& text) + { + Box b; + auto values = juce::StringArray::fromTokens (text, ", ", "\""); + values.removeEmptyStrings(); + + switch (values.size()) + { + case 1: + b.top = T (values [0].getFloatValue()); + b.left = b.top; + b.right = b.top; + b.bottom = b.top; + break; + case 2: + b.top = T (values [0].getFloatValue()); + b.left = T (values [1].getFloatValue()); + b.right = b.left; + b.bottom = b.top; + break; + case 3: + b.top = T (values [0].getFloatValue()); + b.left = T (values [1].getFloatValue()); + b.bottom = T (values [2].getFloatValue()); + b.right = b.left; + break; + case 4: + b.top = T (values [0].getFloatValue()); + b.right = T (values [1].getFloatValue()); + b.bottom = T (values [2].getFloatValue()); + b.left = T (values [3].getFloatValue()); + break; + default: + break; + } + + return b; + } + + juce::Rectangle reducedRect (juce::Rectangle rect) const + { + return rect.withTrimmedTop (top) + .withTrimmedLeft (left) + .withTrimmedRight (right) + .withTrimmedBottom (bottom); + } +}; + +} diff --git a/Layout/foleys_Decorator.cpp b/Layout/foleys_Decorator.cpp index c3bfd65a..a72b9389 100644 --- a/Layout/foleys_Decorator.cpp +++ b/Layout/foleys_Decorator.cpp @@ -42,7 +42,7 @@ void Decorator::drawDecorator (juce::Graphics& g, juce::Rectangle bounds) { juce::Graphics::ScopedSaveState stateSave (g); - auto boundsf = bounds.toFloat().reduced (margin); + auto boundsf = margin.reducedRect (bounds.toFloat()); { juce::Graphics::ScopedSaveState save (g); @@ -123,28 +123,28 @@ void Decorator::updateColours (MagicGUIBuilder& builder, const juce::ValueTree& Decorator::ClientBounds Decorator::getClientBounds (juce::Rectangle overallBounds) const { - auto box = overallBounds.reduced (juce::roundToInt (margin + padding)); + auto box = padding.reducedRect (margin.reducedRect (overallBounds.toFloat())); juce::Rectangle captionBox; if (caption.isNotEmpty()) { if (justification.getOnlyVerticalFlags() & juce::Justification::top) - captionBox = box.removeFromTop (int (captionSize)); + captionBox = box.toNearestInt().removeFromTop (int (captionSize)); else if (justification.getOnlyVerticalFlags() & juce::Justification::bottom) - captionBox = box.removeFromBottom (int (captionSize)); + captionBox = box.toNearestInt().removeFromBottom (int (captionSize)); else { juce::Font f (captionSize * 0.8f); auto w = f.getStringWidth (caption); if (justification.getOnlyHorizontalFlags() & juce::Justification::left) - captionBox = box.removeFromLeft (w); + captionBox = box.toNearestInt().removeFromLeft (w); else if (justification.getOnlyHorizontalFlags() & juce::Justification::right) - captionBox = box.removeFromRight (w); + captionBox = box.toNearestInt().removeFromRight (w); } } - return { box, captionBox }; + return { box.toNearestInt(), captionBox }; } void Decorator::configure (MagicGUIBuilder& builder, const juce::ValueTree& node) @@ -157,11 +157,11 @@ void Decorator::configure (MagicGUIBuilder& builder, const juce::ValueTree& node auto marginVar = builder.getStyleProperty (IDs::margin, node); if (! marginVar.isVoid()) - margin = static_cast (marginVar); + margin = Box::fromString (marginVar.toString()); auto paddingVar = builder.getStyleProperty (IDs::padding, node); if (! paddingVar.isVoid()) - padding = static_cast (paddingVar); + padding = Box::fromString (paddingVar.toString()); auto radiusVar = builder.getStyleProperty (IDs::radius, node); if (! radiusVar.isVoid()) @@ -207,8 +207,8 @@ void Decorator::reset() backgroundColour = juce::Colours::darkgrey; borderColour = juce::Colours::silver; - margin = 5.0f; - padding = 5.0f; + margin = { 5.0f }; + padding = { 5.0f }; border = 0.0f; radius = 5.0f; diff --git a/Layout/foleys_Decorator.h b/Layout/foleys_Decorator.h index 4b6db784..40c884ef 100644 --- a/Layout/foleys_Decorator.h +++ b/Layout/foleys_Decorator.h @@ -73,8 +73,8 @@ class Decorator juce::Colour backgroundColour { juce::Colours::darkgrey }; juce::Colour borderColour { juce::Colours::silver }; - float margin = 5.0f; - float padding = 5.0f; + Box margin { 5.0f }; + Box padding { 5.0f }; float border = 0.0f; float radius = 5.0f; diff --git a/VERSION.md b/VERSION.md index 3ab0aafb..f7eec101 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1,6 +1,11 @@ PluginGuiMagic - Versions history ================================ +1.2.7 +----- + +- Implemented margin and padding with different values on each edge + 1.2.6 ----- diff --git a/foleys_gui_magic.h b/foleys_gui_magic.h index 0e495e4c..61a9214a 100644 --- a/foleys_gui_magic.h +++ b/foleys_gui_magic.h @@ -105,6 +105,7 @@ #include "Helpers/foleys_Conversions.h" #include "Layout/foleys_GradientBackground.h" +#include "Layout/foleys_BoxModel.h" #include "Layout/foleys_Stylesheet.h" #include "Layout/foleys_Decorator.h" #include "Layout/foleys_GuiItem.h" From 543628a8fe9817335a65158c5aa990070ea8326c Mon Sep 17 00:00:00 2001 From: Daniel Walz Date: Wed, 11 Nov 2020 00:48:28 +0100 Subject: [PATCH 2/4] Averted assert in DropShadow --- Layout/foleys_GuiItem.cpp | 6 +++++- VERSION.md | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Layout/foleys_GuiItem.cpp b/Layout/foleys_GuiItem.cpp index 51773d61..f2a94490 100644 --- a/Layout/foleys_GuiItem.cpp +++ b/Layout/foleys_GuiItem.cpp @@ -201,7 +201,11 @@ juce::Rectangle GuiItem::getClientBounds() const void GuiItem::resized() { if (auto* component = getWrappedComponent()) - component->setBounds (getClientBounds()); + { + auto b = getClientBounds(); + component->setVisible (b.getWidth() > 2 && b.getHeight() > 2); + component->setBounds (b); + } } void GuiItem::updateLayout() diff --git a/VERSION.md b/VERSION.md index f7eec101..3365473c 100644 --- a/VERSION.md +++ b/VERSION.md @@ -5,6 +5,8 @@ PluginGuiMagic - Versions history ----- - Implemented margin and padding with different values on each edge +- Averted an assert in DropShadow with Sliders (or Components in General) + becoming only one pixel 1.2.6 ----- From 234a64b3d3f17203346e2fa7f12d326a6d4a9877 Mon Sep 17 00:00:00 2001 From: Daniel Walz Date: Wed, 11 Nov 2020 01:28:48 +0100 Subject: [PATCH 3/4] Fixed regression bug with caption --- General/foleys_MagicPluginEditor.cpp | 2 +- Layout/foleys_Decorator.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/General/foleys_MagicPluginEditor.cpp b/General/foleys_MagicPluginEditor.cpp index 7ada62d1..98607cd9 100644 --- a/General/foleys_MagicPluginEditor.cpp +++ b/General/foleys_MagicPluginEditor.cpp @@ -121,8 +121,8 @@ void MagicPluginEditor::updateSize() int minHeight = rootNode.getProperty (IDs::minHeight, 10); int maxWidth = rootNode.getProperty (IDs::maxWidth, std::numeric_limits::max()); int maxHeight = rootNode.getProperty (IDs::maxHeight, std::numeric_limits::max()); - setResizeLimits (minWidth, minHeight, maxWidth, maxHeight); setResizable (resizable, resizeCorner); + setResizeLimits (minWidth, minHeight, maxWidth, maxHeight); } setSize (width, height); diff --git a/Layout/foleys_Decorator.cpp b/Layout/foleys_Decorator.cpp index a72b9389..1bd1125f 100644 --- a/Layout/foleys_Decorator.cpp +++ b/Layout/foleys_Decorator.cpp @@ -129,18 +129,18 @@ Decorator::ClientBounds Decorator::getClientBounds (juce::Rectangle overall if (caption.isNotEmpty()) { if (justification.getOnlyVerticalFlags() & juce::Justification::top) - captionBox = box.toNearestInt().removeFromTop (int (captionSize)); + captionBox = box.removeFromTop (captionSize).toNearestInt(); else if (justification.getOnlyVerticalFlags() & juce::Justification::bottom) - captionBox = box.toNearestInt().removeFromBottom (int (captionSize)); + captionBox = box.removeFromBottom (captionSize).toNearestInt(); else { juce::Font f (captionSize * 0.8f); auto w = f.getStringWidth (caption); if (justification.getOnlyHorizontalFlags() & juce::Justification::left) - captionBox = box.toNearestInt().removeFromLeft (w); + captionBox = box.removeFromLeft (w).toNearestInt(); else if (justification.getOnlyHorizontalFlags() & juce::Justification::right) - captionBox = box.toNearestInt().removeFromRight (w); + captionBox = box.removeFromRight (w).toNearestInt(); } } From b069da1c4bb1a21d81535a3150722295f97ad3d0 Mon Sep 17 00:00:00 2001 From: Daniel Walz Date: Thu, 3 Dec 2020 18:13:07 +0100 Subject: [PATCH 4/4] Added option to XY-Dragger for radius and sensitivity --- General/foleys_MagicJUCEFactories.cpp | 14 ++++++++++++++ VERSION.md | 1 + Widgets/foleys_XYDragComponent.cpp | 26 +++++++++++++++++--------- Widgets/foleys_XYDragComponent.h | 6 +++++- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/General/foleys_MagicJUCEFactories.cpp b/General/foleys_MagicJUCEFactories.cpp index 7942102d..122c5273 100644 --- a/General/foleys_MagicJUCEFactories.cpp +++ b/General/foleys_MagicJUCEFactories.cpp @@ -478,6 +478,8 @@ class XYDraggerItem : public GuiItem static const juce::Identifier pCrosshair; static const juce::StringArray pCrosshairTypes; + static const juce::Identifier pRadius; + static const juce::Identifier pSenseFactor; XYDraggerItem (MagicGUIBuilder& builder, const juce::ValueTree& node) : GuiItem (builder, node) @@ -523,6 +525,14 @@ class XYDraggerItem : public GuiItem dragger.setCrossHair (false, true); else dragger.setCrossHair (true, true); + + auto radius = getProperty (pRadius); + if (! radius.isVoid()) + dragger.setRadius (radius); + + auto factor = getProperty (pSenseFactor); + if (! factor.isVoid()) + dragger.setSenseFactor (factor); } std::vector getSettableProperties() const override @@ -533,6 +543,8 @@ class XYDraggerItem : public GuiItem props.push_back ({ configNode, IDs::parameterY, SettableProperty::Choice, {}, magicBuilder.createParameterMenuLambda() }); props.push_back ({ configNode, "right-click", SettableProperty::Choice, {}, magicBuilder.createParameterMenuLambda() }); props.push_back ({ configNode, pCrosshair, SettableProperty::Choice, {}, magicBuilder.createChoicesMenuLambda (pCrosshairTypes) }); + props.push_back ({ configNode, pRadius, SettableProperty::Number, {}, {}}); + props.push_back ({ configNode, pSenseFactor, SettableProperty::Number, {}, {}}); return props; } @@ -549,6 +561,8 @@ class XYDraggerItem : public GuiItem }; const juce::Identifier XYDraggerItem::pCrosshair { "xy-crosshair" }; const juce::StringArray XYDraggerItem::pCrosshairTypes { "no-crosshair", "vertical", "horizontal", "crosshair" }; +const juce::Identifier XYDraggerItem::pRadius { "xy-radius" }; +const juce::Identifier XYDraggerItem::pSenseFactor { "xy-sense-factor" }; //============================================================================== diff --git a/VERSION.md b/VERSION.md index 3365473c..c8c02e72 100644 --- a/VERSION.md +++ b/VERSION.md @@ -7,6 +7,7 @@ PluginGuiMagic - Versions history - Implemented margin and padding with different values on each edge - Averted an assert in DropShadow with Sliders (or Components in General) becoming only one pixel +- Added option to XY-Dragger for radius and sensitivity 1.2.6 ----- diff --git a/Widgets/foleys_XYDragComponent.cpp b/Widgets/foleys_XYDragComponent.cpp index 38d10a0f..e60c8668 100644 --- a/Widgets/foleys_XYDragComponent.cpp +++ b/Widgets/foleys_XYDragComponent.cpp @@ -38,9 +38,6 @@ namespace foleys { - -float XYDragComponent::radius = 4.0f; - XYDragComponent::XYDragComponent() { setOpaque (false); @@ -113,13 +110,24 @@ void XYDragComponent::setRightClickParameter (juce::RangedAudioParameter* parame contextMenuParameter = parameter; } +void XYDragComponent::setRadius (float radiusToUse) +{ + radius = radiusToUse; + repaint(); +} + +void XYDragComponent::setSenseFactor (float factor) +{ + senseFactor = factor; +} + void XYDragComponent::updateWhichToDrag (juce::Point pos) { const auto centre = juce::Point (getXposition(), getYposition()).toFloat(); - mouseOverDot = (centre.getDistanceFrom (pos) < radius * 1.5f); - mouseOverX = (wantsHorizontalDrag && std::abs (pos.getX() - centre.getX()) < 3.0f); - mouseOverY = (wantsVerticalDrag && std::abs (pos.getY() - centre.getY()) < 3.0f); + mouseOverDot = (centre.getDistanceFrom (pos) < radius * senseFactor); + mouseOverX = (wantsHorizontalDrag && std::abs (pos.getX() - centre.getX()) < senseFactor + 1.0f); + mouseOverY = (wantsVerticalDrag && std::abs (pos.getY() - centre.getY()) < senseFactor + 1.0f); repaint(); } @@ -129,13 +137,13 @@ bool XYDragComponent::hitTest (int x, int y) const auto click = juce::Point (x, y).toFloat (); const auto centre = juce::Point (getXposition (), getYposition ()).toFloat (); - if (centre.getDistanceFrom (click) < radius * 1.5f) + if (centre.getDistanceFrom (click) < radius * senseFactor) return true; - if (wantsHorizontalDrag && std::abs (click.getX() - centre.getX()) < 3.0f) + if (wantsHorizontalDrag && std::abs (click.getX() - centre.getX()) < senseFactor + 1.0f) return true; - if (wantsVerticalDrag && std::abs (click.getY() - centre.getY()) < 3.0f) + if (wantsVerticalDrag && std::abs (click.getY() - centre.getY()) < senseFactor + 1.0f) return true; return false; diff --git a/Widgets/foleys_XYDragComponent.h b/Widgets/foleys_XYDragComponent.h index e6c11b2b..d617b49c 100644 --- a/Widgets/foleys_XYDragComponent.h +++ b/Widgets/foleys_XYDragComponent.h @@ -66,6 +66,9 @@ class XYDragComponent : public juce::Component void setRightClickParameter (juce::RangedAudioParameter* parameter); + void setRadius (float radius); + void setSenseFactor (float factor); + bool hitTest (int x, int y) override; void mouseDown (const juce::MouseEvent&) override; void mouseMove (const juce::MouseEvent&) override; @@ -93,7 +96,8 @@ class XYDragComponent : public juce::Component juce::RangedAudioParameter* contextMenuParameter = nullptr; - static float radius; + float radius = 4.0f; + float senseFactor = 2.0f; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XYDragComponent) };