From 71af017983d5821bddf3898cc6215ce55ac88de3 Mon Sep 17 00:00:00 2001 From: Christoph Hart <> Date: Sat, 28 Sep 2024 16:48:03 +0200 Subject: [PATCH] - some more work on dynamic container component --- currentGitHash.txt | 2 +- hi_backend/backend/currentGit.h | 2 +- .../api}/DynamicComponentContainer.cpp | 114 ++++++++++++++---- .../api}/DynamicComponentContainer.h | 43 ++++--- 4 files changed, 119 insertions(+), 42 deletions(-) rename {projects/standalone/Source => hi_scripting/scripting/api}/DynamicComponentContainer.cpp (88%) rename {projects/standalone/Source => hi_scripting/scripting/api}/DynamicComponentContainer.h (94%) diff --git a/currentGitHash.txt b/currentGitHash.txt index 7e181565a..9d7d7f444 100644 --- a/currentGitHash.txt +++ b/currentGitHash.txt @@ -1 +1 @@ -966fbd21d4d4cfd93d0fd0ee84d4eccfa37b8f94 +6cdf5de799ddc4f796aca7d242a990dfef10b733 diff --git a/hi_backend/backend/currentGit.h b/hi_backend/backend/currentGit.h index d83fc64eb..1fcf74e66 100644 --- a/hi_backend/backend/currentGit.h +++ b/hi_backend/backend/currentGit.h @@ -1 +1 @@ -#define PREVIOUS_HISE_COMMIT "966fbd21d4d4cfd93d0fd0ee84d4eccfa37b8f94" +#define PREVIOUS_HISE_COMMIT "6cdf5de799ddc4f796aca7d242a990dfef10b733" diff --git a/projects/standalone/Source/DynamicComponentContainer.cpp b/hi_scripting/scripting/api/DynamicComponentContainer.cpp similarity index 88% rename from projects/standalone/Source/DynamicComponentContainer.cpp rename to hi_scripting/scripting/api/DynamicComponentContainer.cpp index 6a87459ec..992bdc020 100644 --- a/projects/standalone/Source/DynamicComponentContainer.cpp +++ b/hi_scripting/scripting/api/DynamicComponentContainer.cpp @@ -83,12 +83,8 @@ template struct WrapperBase: public Base } }; - - virtual ~WrapperBase() {}; - SN_NODE_ID(); - void resized() override { component.setBounds(getLocalBounds()); @@ -219,6 +215,11 @@ struct Slider: public WrapperBase this->component.setDoubleClickReturnValue(true, (double)this->dataTree[dcid::defaultValue]); this->component.setTextBoxStyle(juce::Slider::NoTextBox, false, 0, 0); + this->component.onValueChange = [this]() + { + this->data->onValueChange (getId(), this->component.getValue(), this->useUndoManager()); + }; + initSpecialProperties({ dcid::min, dcid::max, @@ -384,6 +385,10 @@ struct DragContainer: public Base { auto idSelector = String("#") + getId().toString(); getProperties().set(dcid::id, idSelector); + + isVertical = v.getProperty(dcid::isVertical, true); + dragMargin = v.getProperty(dcid::dragMargin, 3); + animationSpeed = v.getProperty(dcid::animationSpeed, 150); } static Base* createComponent(Data::Ptr d, const ValueTree& v) { return new DragContainer(d, v); } @@ -404,7 +409,7 @@ struct DragContainer: public Base void rebuildPositions(bool writePositionsInValueTree) { - auto b = getLocalBounds().reduced(2); + auto b = getLocalBounds().reduced(dragMargin); for(auto& idx: currentIndexes) { @@ -421,14 +426,12 @@ struct DragContainer: public Base continue; if(writePositionsInValueTree) - { dynamic_cast(c)->writePositionInValueTree(tb, false); - c->setBounds(tb); - } + + if(animationSpeed == 0) + c->setBounds (tb); else - { - Desktop::getInstance().getAnimator().animateComponent(c, tb, 1.0, 200, false, 1.0, 0.3); - } + Desktop::getInstance().getAnimator().animateComponent(c, tb, 1.0, 200, false, 1.0, 0.3); } } } @@ -501,7 +504,10 @@ struct DragContainer: public Base void checkBounds (Rectangle& bounds, const Rectangle& previousBounds, const Rectangle& limits, bool , bool, bool, bool) override { - auto parentArea = parent.getLocalBounds().reduced(2,0); + auto x = parent.isVertical ? parent.dragMargin : 0; + auto y = parent.isVertical ? 0 : parent.dragMargin; + + auto parentArea = parent.getLocalBounds().reduced(x, y); bounds = bounds.constrainedWithin(parentArea); } @@ -548,37 +554,79 @@ struct DragContainer: public Base struct Sorter { - Sorter(bool isVertical_): - isVertical(isVertical_) + Sorter(bool isVertical_, int maxValue_): + isVertical(isVertical_), + maxValue(maxValue_) {}; int compareElements(Component* c1, Component* c2) const { - int pos1, pos2; + int pos1, pos2, b1, b2, l1, l2; if(isVertical) { pos1 = c1->getY(); pos2 = c2->getY(); + b1 = c1->getBottom(); + b2 = c2->getBottom(); + l1 = c1->getHeight(); + l2 = c2->getHeight(); } else { pos1 = c1->getX(); pos2 = c2->getX(); + b1 = c1->getRight(); + b2 = c2->getRight(); + l1 = c1->getWidth(); + l2 = c2->getWidth(); + } + + auto h1 = pos1 + l1/2; + auto h2 = pos2 + l2/2; + + if(l1 == l2) + { + if(pos1 < pos2) + return -1; + if(pos1 > pos2) + return 1; + } + if(l1 < l2) + { + if(h1 < h2) + return -1; + if(h1 > h2) + return 1; + } + if(l1 > l2) + { + if(pos1 == 0 && pos2 != 0) + return -1; + if(pos2 == 0 && pos1 != 0) + return 1; + + if(b1 == maxValue && b2 != maxValue) + return 1; + if(b1 == maxValue && b2 != maxValue) + return -1; + + if(h1 < h2) + return -1; + if(h1 > h2) + return 1; } - if(pos1 < pos2) - return -1; - if(pos1 > pos2) - return 1; + return 0; } const bool isVertical; + const int maxValue; }; - Sorter s(isVertical); + Sorter s(isVertical, isVertical ? getHeight() : getWidth()); Array sorted; sorted.addArray(list); @@ -595,6 +643,8 @@ struct DragContainer: public Base } bool isVertical = true; + double animationSpeed = 150.0; + int dragMargin = 3; Array currentIndexes; OwnedArray draggers; @@ -725,7 +775,7 @@ Base::Base(Data::Ptr d, const ValueTree& v): dataTree(v), valueReference(data->getValueTree(Data::TreeType::Values)) { - basicPropertyListener.setCallback(dataTree, { dcid::enabled, dcid::visible}, valuetree::AsyncMode::Asynchronously, BIND_MEMBER_FUNCTION_2(Base::updateBasicProperties)); + basicPropertyListener.setCallback(dataTree, { dcid::enabled, dcid::visible, dcid::class_, dcid::elementStyle}, valuetree::AsyncMode::Asynchronously, BIND_MEMBER_FUNCTION_2(Base::updateBasicProperties)); positionListener.setCallback(dataTree, { dcid::x, dcid::y, dcid::width, dcid::height}, valuetree::AsyncMode::Coallescated, BIND_MEMBER_FUNCTION_2(Base::updatePosition)); childListener.setCallback(dataTree, valuetree::AsyncMode::Asynchronously, BIND_MEMBER_FUNCTION_2(Base::updateChild)); @@ -771,6 +821,26 @@ void Base::updateChild(const ValueTree& v, bool wasAdded) void Base::updateBasicProperties(const Identifier& id, const var& newValue) { + if(id == dcid::class_) + { + auto classes = StringArray::fromTokens(newValue.toString(), " ", ""); + + auto c = getCSSTarget(); + + auto existingClasses = simple_css::FlexboxComponent::Helpers::getClassSelectorFromComponentClass(c); + + for(auto cl: existingClasses) + classes.add(cl.toString()); + + classes.removeDuplicates(false); + classes.removeEmptyStrings(); + + simple_css::FlexboxComponent::Helpers::writeSelectorsToProperties(*c, classes); + } + if(id == dcid::elementStyle) + { + simple_css::FlexboxComponent::Helpers::writeInlineStyle (*getCSSTarget(), newValue.toString()); + } if(id == dcid::enabled) setEnabled((bool)newValue); if(id == dcid::visible) @@ -834,4 +904,4 @@ Root::Root(Data::Ptr d): } } // namespace dyncomp -} // namespace hise \ No newline at end of file +} // namespace hise diff --git a/projects/standalone/Source/DynamicComponentContainer.h b/hi_scripting/scripting/api/DynamicComponentContainer.h similarity index 94% rename from projects/standalone/Source/DynamicComponentContainer.h rename to hi_scripting/scripting/api/DynamicComponentContainer.h index 68b628c37..b49b06018 100644 --- a/projects/standalone/Source/DynamicComponentContainer.h +++ b/hi_scripting/scripting/api/DynamicComponentContainer.h @@ -31,22 +31,8 @@ */ #pragma once -#include "hi_tools/simple_css/StyleSheet.h" -/** TODO: - * - - * - implement all important properties: - * - All: tooltip, useUndoManager, defaultValue OK - * - Button: isMomentary, radioGroupId, setValueOnClick OK - * - ComboBox: useCustomPopup OK - * - Slider: min, max, middlePosition, stepSize, mode, suffix, style, showValuePopup - * - add filmstrip logic - * - Label: editable, multiline, updateEachKey - * - move to scripting object - * - * */ namespace hise { namespace dyncomp { @@ -70,6 +56,9 @@ namespace dcid DECLARE_ID(defaultValue); DECLARE_ID(useUndoManager); + static const Identifier class_("class"); + DECLARE_ID(elementStyle); + DECLARE_ID(parentComponent); DECLARE_ID(x); DECLARE_ID(y); @@ -94,7 +83,7 @@ namespace dcid DECLARE_ID(stepSize); DECLARE_ID(mode); DECLARE_ID(suffix); - DECLARE_ID(style); + DECLARE_ID(style); DECLARE_ID(showValuePopup); DECLARE_ID(filmstripImage); @@ -102,6 +91,9 @@ namespace dcid DECLARE_ID(isVertical); DECLARE_ID(scaleFactor); + DECLARE_ID(animationSpeed); + DECLARE_ID(dragMargin); + } #undef DECLARE_ID @@ -254,6 +246,8 @@ struct Base: public Component, protected: + virtual Component* getCSSTarget() { return this; } + Data::Ptr data; ValueTree dataTree; ValueTree valueReference; @@ -315,7 +309,7 @@ struct TestComponent: public Component cssEditor.tokenCollection = new mcl::TokenCollection("CSS"); cssEditor.setLanguageManager(new simple_css::LanguageManager(cssDoc)); - + addAndMakeVisible(cssEditor); addAndMakeVisible(jsonEditor); @@ -380,14 +374,27 @@ struct TestComponent: public Component { auto refPath = ref.fromLastOccurrenceOf("}", false, false); +#if JUCE_MAC + auto imgFile = File("/Users/christophhart/Development/HiseSnippets/Assets/Images").getChildFile(refPath); + +#else auto imgFile = File("D:/Development/HISE Snippets/Assets/Images").getChildFile(refPath); +#endif PNGImageFormat iff; return iff.loadFrom(imgFile); }, [this](const String& fontName, const String& url) { auto refPath = url.fromLastOccurrenceOf("}", false, false); - auto fontFile = File("D:/Development/HISE Snippets/Assets/Images").getChildFile(refPath); + + + +#if JUCE_MAC + auto fontFile = File("/Users/christophhart/Development/HiseSnippets/Assets/Images").getChildFile(refPath); + +#else + auto fontFile = File("D:/Development/HISE Snippets/Assets/Images").getChildFile(refPath); +#endif MemoryBlock mb; @@ -496,4 +503,4 @@ struct TestComponent: public Component } // namespace dyncomp -} // namespace hise \ No newline at end of file +} // namespace hise