diff --git a/CrystalizerEQ/AXIOMDesignSystem.h b/CrystalizerEQ/AXIOMDesignSystem.h index 9577cd7..23f824b 100644 --- a/CrystalizerEQ/AXIOMDesignSystem.h +++ b/CrystalizerEQ/AXIOMDesignSystem.h @@ -139,7 +139,7 @@ namespace AXIOM { case uiScaleMode::XL: scale.uiScale = 1.75f; break; } - scale.uiScale = juce::jlimit(0.6f, 3.0f, scale.uiScale); + scale.uiScale = juce::jlimit(0.3f, 3.0f, scale.uiScale); } }; @@ -355,6 +355,7 @@ namespace AXIOM { struct Opacity { static constexpr float MINALPHA = 0.04f; static constexpr float MAXALPHA = 0.95f; + static constexpr float MUTEDMUL = 0.5f; struct AlphaToken { enum class Role { Text, Icon, Surface, Overlay, Stroke, FocusGlow, Disabled, InteractiveFill @@ -382,7 +383,7 @@ namespace AXIOM { alphaFactor = fromRole(role); } alphaFactor += fromState(state); - if (state == AlphaToken::State::Disabled) alphaFactor *= 0.5f; + if (state == AlphaToken::State::Disabled) alphaFactor *= MUTEDMUL; alphaFactor = std::clamp(alphaFactor, MINALPHA, MAXALPHA); return alphaFactor; } @@ -427,8 +428,90 @@ namespace AXIOM { } }; - struct Motion { - }; + /*struct Motion { + enum class Duration { + Slowest, + Slow, + Moderate, + Regular, + Fast + }; + enum class Ease { + Standard, + Decel, + Accel, + Emphasized, + Overshoot + }; + enum class Spring{ + Snappy, + Natural, + Gentle, + SoftOvershoot + }; + enum class MotionRole { + MenuEnter, MenuExit, ModalEnter, TooltipEnter, TooltipExit + }; + enum class MotionMicro { + Hover, Pressed, Focus, Success, Error + }; + enum class StaggerProfile { + Forward, CenterOut, Reverse + }; + + struct CubicBezier { + float x1, y1, x2, y2; + }; + struct SpringParameters { + float tension, friction, damping, mass; + }; + struct MicroParameters { + float scaleDelta, opacityDelta; + Duration duration; + Ease ease; + }; + + static float getDuration(Duration duration) { + switch (duration) { + case Duration::Slowest: return 0.36f; + case Duration::Slow: return 0.28f; + case Duration::Moderate: return 0.2f; + case Duration::Regular: return 0.14f; + case Duration::Fast: return 0.09f; + } + return 0.2f; + } + static CubicBezier getEasing(Ease easing) { + switch (easing) { + case Ease::Standard: return {0.2f, 0.0f, 0.0f, 1.0f}; + case Ease::Decel: return {0.05f, 0.7f, 0.1f, 1.0f}; + case Ease::Accel: return {0.3f, 0.0f, 0.8f, 0.15f}; + case Ease::Emphasized: return {0.2f, 0.0f, 0.0f, 1.0f}; + default: return {0.2f, 0.0f, 0.0f, 1.0f};; + // EIGENES STRUCT SPRING case Ease::Overshoot: return {0.2f, 0.0f, 0.0f, 1.0f}; + } + } + static SpringParameters getSpringPreset(Spring mode) { + switch (mode) { + case Spring::Snappy: return {220.0f, 26.0f, 0.6f, 1.0f}; + case Spring::Natural: return {170.0f, 22.0f, 0.68f, 1.0f}; + case Spring::Gentle: return {120.0f, 20.0f, 0.75f, 1.0f}; + case Spring::SoftOvershoot: return {180.0f, 17.0f, 0.55f, 1.0f}; + } + return {170.0f, 22.0f, 0.68f, 1.0f}; + } + static MicroParameters getMicroPreset(MotionMicro mode) { + switch (mode) { + case MotionMicro::Hover: return {0.02f, 0.06f, Duration::Fast, Ease::Emphasized}; + case MotionMicro::Pressed: return {-0.02f, 0.0f, Duration::Fast, Ease::Standard}; + case MotionMicro::Focus: return {0.0f, 0.02f, Duration::Regular, Ease::Decel}; + case MotionMicro::Success: return {0.04f, 0.04f, Duration::Regular, Ease::Emphasized}; + case MotionMicro::Error: return {0.00f, 0.00f, Duration::Fast, Ease::Standard}; + } + return {0.0f, 0.0f, Duration::Regular, Ease::Standard}; + } + + };*/ struct Components { struct ButtonStyles { @@ -451,6 +534,132 @@ namespace AXIOM { }; struct Layout { + + /// + /// @param mode Spacing mode -- e.g. Spacing::SizeMode::XS + /// @return Gap size in px as int + static int gap(Spacing::SizeMode mode) { + return juce::roundToInt(Spacing::scale.space(mode)); + } + + static juce::BorderSize padding(Spacing::SizeMode mode) { + if (mode == Spacing::SizeMode::XS) return {0, 0, 0, 0}; + const int px = gap(mode); + return juce::BorderSize{px, px, px, px}; + } + + static juce::Rectangle content(juce::Rectangle rect, juce::BorderSize pad) { + rect = pad.subtractedFrom(rect); + return rect; + } + + static juce::FlexItem flexItem(juce::Component& component, + float flexGrow = 1.f, + float flexShrink = 1.f, + float basisPx = -1.f, + Spacing::SizeMode margin = Spacing::SizeMode::XS) { + + juce::FlexItem item{ component }; + item.flexGrow = flexGrow; + item.flexShrink = flexShrink; + + if (basisPx >= 0.f) + item.flexBasis = basisPx; + + const float half = (float) gap(margin) * 0.5f; + item.margin = juce::FlexItem::Margin{ half, half, half, half }; + + return item; + } + + static void flexRow(juce::Rectangle bounds, + juce::Array items, + Spacing::SizeMode gapSize, + juce::FlexBox::JustifyContent justifyContent, + juce::FlexBox::AlignItems alignItems + ) { + const auto pad = padding(gapSize); + juce::FlexBox fb; + fb.flexDirection = juce::FlexBox::Direction::row; + fb.flexWrap = juce::FlexBox::Wrap::noWrap; + fb.justifyContent = justifyContent; + fb.alignItems = alignItems; + + fb.items.addArray(items); + + fb.performLayout(content(bounds, pad)); + + } + + static void flexColumn(juce::Rectangle bounds, + juce::Array items, + Spacing::SizeMode gapSize, + juce::FlexBox::JustifyContent justifyContent, + juce::FlexBox::AlignItems alignItems + ) { + const auto pad = padding(gapSize); + juce::FlexBox fb; + fb.flexDirection = juce::FlexBox::Direction::column; + fb.flexWrap = juce::FlexBox::Wrap::noWrap; + fb.justifyContent = justifyContent; + fb.alignItems = alignItems; + + fb.items.addArray(items); + fb.performLayout(content(bounds, pad)); + } + + static juce::Grid::TrackInfo fr(float value) { + jassert(value > 0.0f); + return juce::Grid::TrackInfo{juce::Grid::Fr{juce::roundToInt(value)}}; + } + + static juce::Grid::TrackInfo pxTrack(float value) { + jassert(value >= 0.0f); + return juce::Grid::TrackInfo{juce::Grid::Px{value}}; + } + + static juce::Grid::Px px(float value) { + jassert(value >= 0.0f); + return juce::Grid::Px{value}; + } + + struct GridSpec { + std::vector cols; + std::vector rows; + Spacing::SizeMode colGap { Spacing::SizeMode::M }; + Spacing::SizeMode rowGap { Spacing::SizeMode::M }; + juce::BorderSize pad { 0, 0, 0, 0 }; + }; + + static juce::GridItem area(juce::Component& c, + int rowStart, int colStart, + int rowEnd, int colEnd) + { + return juce::GridItem(c).withArea(rowStart, colStart, rowEnd, colEnd); + } + + static void grid(juce::Rectangle bounds, + const GridSpec& spec, + std::initializer_list children, + juce::Grid::AutoFlow autoFlow = juce::Grid::AutoFlow::row) { + juce::Grid g; + + for (const auto& t : spec.cols) g.templateColumns.add(t); + for (const auto& t : spec.rows) g.templateRows.add(t); + + g.autoFlow = autoFlow; + g.autoColumns = juce::Grid::TrackInfo(juce::Grid::Fr(1)); + g.autoRows = juce::Grid::TrackInfo(juce::Grid::Fr(1)); + + g.columnGap = px((float) gap(spec.colGap)); + g.rowGap = px((float) gap(spec.rowGap)); + + for (const auto& c : children) + g.items.add(c); + + const auto inner = spec.pad.subtractedFrom(bounds); + g.performLayout(inner); + } }; private diff --git a/CrystalizerEQ/PluginEditor.cpp b/CrystalizerEQ/PluginEditor.cpp index 44bb8dd..cec0fca 100644 --- a/CrystalizerEQ/PluginEditor.cpp +++ b/CrystalizerEQ/PluginEditor.cpp @@ -18,6 +18,7 @@ using Spacing = DesignSystem::Spacing; using Shape = DesignSystem::Shape; using Opacity = DesignSystem::Opacity; +using Layout = DesignSystem::Layout; //============================================================================== @@ -27,16 +28,54 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize // Make sure that before the constructor has finished, you've set the // editor's size to whatever you need it to be. - setSize (1280, 480); + setSize (1280, 720); // these define the parameters of our slider object startTimerHz(60); - Spacing::setUiScale(Spacing::uiScaleMode::L); + addAndMakeVisible(headerBar); + headerBar.addAndMakeVisible(titleLabel); + + headerBar.addAndMakeVisible(presetArea); + presetArea.addAndMakeVisible(presetBoxLabel); + presetArea.addAndMakeVisible(resetButton); + presetArea.addAndMakeVisible(presetBox); + presetArea.addAndMakeVisible(presetMenuButton); + + + addAndMakeVisible(mainPanel); + mainPanel.addAndMakeVisible(analyzerArea); + + { + mainPanel.addAndMakeVisible(filterArea); + + { + filterArea.addAndMakeVisible(lowFilterArea); + lowFilterArea.addAndMakeVisible(lowBandModeBox); + lowFilterArea.addAndMakeVisible(lowBandSlopeLabel); + lowFilterArea.addAndMakeVisible(lowBandGainLabel); + lowFilterArea.addAndMakeVisible(lowBandQLabel); + lowFilterArea.addAndMakeVisible(lowBandFreqLabel); + lowFilterArea.addAndMakeVisible(lowBandSlopeSlider); + lowFilterArea.addAndMakeVisible(lowBandGainSlider); + lowFilterArea.addAndMakeVisible(lowBandQSlider); + lowFilterArea.addAndMakeVisible(lowBandFreqSlider); + } + + filterArea.addAndMakeVisible(lowMidFilterArea); + + filterArea.addAndMakeVisible(midFilterArea); + + filterArea.addAndMakeVisible(highMidFilterArea); + + filterArea.addAndMakeVisible(highFilterArea); + + } + addAndMakeVisible(footerBar); + Spacing::setDensity(Spacing::DensityMode::Wide); titleLabel.setText("Crystalizer", juce::dontSendNotification); - addAndMakeVisible(titleLabel); @@ -56,13 +95,10 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize setupLabel (lowBandGainLabel, "LowBand Gain"); setupLabel(lowBandQLabel, "LowBand Q"); - addAndMakeVisible (lowBandFreqLabel); - addAndMakeVisible (lowBandSlopeLabel); - addAndMakeVisible(lowBandGainLabel); - addAndMakeVisible(lowBandQLabel); + lowBandModeBox.setJustificationType (juce::Justification::centred); - addAndMakeVisible (lowBandModeBox); + //PEAK 1 setupLabel (peak1FreqLabel,"Low-Mid Freq"); setupLabel (peak1GainLabel,"Low-Mid Gain"); @@ -118,7 +154,6 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize auto presets = audioProcessor.getPresetNamesArray(); presetBox.addItemList(presets, 1); presetBox.setSelectedId(1, juce::dontSendNotification); - addAndMakeVisible(presetBox); presetMenuButton.setName("PresetMenuButton"); @@ -126,7 +161,6 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize presetMenuButton.setColour (juce::ToggleButton::textColourId, juce::Colours::black); presetMenuButton.setColour(juce::ToggleButton::tickColourId, juce::Colours::black); presetMenuButton.setToggleState(false, juce::dontSendNotification); - addAndMakeVisible(presetMenuButton); addAndMakeVisible(savePresetButton); addAndMakeVisible(deletePresetButton); @@ -188,7 +222,6 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize { s->setSliderStyle (style); s->setTextBoxStyle (juce::Slider::TextBoxBelow, true, 70, 18); - addAndMakeVisible (*s); s->setColour (juce::Slider::textBoxTextColourId, juce::Colours::black); } @@ -316,7 +349,6 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize addAndMakeVisible (crystalizeButton); - addAndMakeVisible (resetButton); addAndMakeVisible (masterBypassButton); @@ -331,6 +363,8 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize savePresetButton.setVisible(false); deletePresetButton.setVisible(false); + setupLabel(presetBoxLabel, "Presets"); + testNoiseButton.onClick = [this]() { if (auto* param = audioProcessor.apvts.getParameter("TestNoiseEnabled")) @@ -472,7 +506,7 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g) g.setColour (AXIOM::DesignSystem::Colours::FOREGROUNDCOLOUR); - //SPACING TESTING + /*//SPACING TESTING const float gap = Spacing::scale.space(Spacing::SizeMode::M); auto r = getLocalBounds().toFloat(); r = r.reduced(gap); @@ -492,18 +526,86 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g) const juce::Colour testColour2 = Colours::ACCENTCOLOUR; g.setColour (testColour2); - g.fillRoundedRectangle(r.getX() * 3, r.getY(), gap, gap * 2, radius); + g.fillRoundedRectangle(r.getX() * 3, r.getY(), gap, gap * 2, radius);*/ + if constexpr (true) // -> auf false setzen, wenn nicht gebraucht + { + + for (auto* c : getChildren()) // headerBar, mainPanel, footerBar + { + auto r = c->getBounds(); + g.setColour(juce::Colours::magenta.withAlpha(0.9f)); + g.drawRect(r, 1.0f); // nur Rahmen, kein fillRect + g.setColour(juce::Colours::white); + g.drawText(c->getName(), r, juce::Justification::centred, false); + } + for (auto* c : headerBar.getChildren()) + { + + auto r = c->getBounds(); // <-- lokal zu headerBar + r = r.translated(headerBar.getX(), headerBar.getY()); // <-- in Editor-Koordinaten bringen! + g.setColour(juce::Colours::cyan.withAlpha(0.3f)); + g.fillRect(r); + g.setColour(juce::Colours::cyan.withAlpha(0.9f)); + g.drawRect(r, 1.0f); + } + for (auto* c : presetArea.getChildren()) + { + auto r = c->getBounds(); // lokal in presetArea + r = r.translated(headerBar.getX() + presetArea.getX(), + headerBar.getY() + presetArea.getY()); // beide Offsets addieren + g.setColour(juce::Colours::yellow.withAlpha(0.3f)); + g.fillRect(r); + g.setColour(juce::Colours::yellow.withAlpha(0.9f)); + g.drawRect(r, 1.0f); + } + + for (auto* c : mainPanel.getChildren()) + { + + auto r = c->getBounds(); // <-- lokal zu headerBar + r = r.translated(mainPanel.getX(), mainPanel.getY()); // <-- in Editor-Koordinaten bringen! + g.setColour(juce::Colours::cyan.withAlpha(0.3f)); + g.fillRect(r); + g.setColour(juce::Colours::cyan.withAlpha(0.9f)); + g.drawRect(r, 1.0f); + } + + + + for (auto* c : filterArea.getChildren()) + { + auto r = c->getBounds(); // lokal in presetArea + r = r.translated(mainPanel.getX() + filterArea.getX(), + mainPanel.getY() + filterArea.getY()); // beide Offsets addieren + g.setColour(juce::Colours::yellow.withAlpha(0.3f)); + g.fillRect(r); + g.setColour(juce::Colours::yellow.withAlpha(0.9f)); + g.drawRect(r, 1.0f); + } + + for (auto* c : lowFilterArea.getChildren()) + { + auto r = getLocalArea(&lowFilterArea, c->getBounds()); // lokal in presetArea + + g.setColour(juce::Colours::cyan.withAlpha(0.3f)); + g.fillRect(r); + g.setColour(juce::Colours::cyan.withAlpha(0.9f)); + g.drawRect(r, 1.0f); + } + + } //ANALYZER // VERSTEHEN!!!!!! - if (! analyzerArea.isEmpty()) + + if (! analyzerRect.isEmpty()) { juce::Graphics::ScopedSaveState guard(g); // Clip/Rückbau automatisch - g.reduceClipRegion(analyzerArea); // auf Sub-Rect beschneiden + g.reduceClipRegion(analyzerRect); // auf Sub-Rect beschneiden - auto r = analyzerArea.toFloat(); + auto r = analyzerRect.toFloat(); // Hintergrund des Analyzer-Bereichs g.setColour(juce::Colours::black); @@ -581,7 +683,7 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g) // Rahmen (optional) g.setColour(juce::Colours::grey); - g.drawRect(analyzerArea); + g.drawRect(analyzerRect); } } @@ -616,7 +718,7 @@ void CrystalizerEQAudioProcessorEditor::timerCallback() highBandQLabel .setVisible(highMode >= 1); // optional: Layout neu berechnen, damit keine Lücke bleibt spectrumAnalyzer.processSamples(); - repaint(analyzerArea); + repaint(analyzerRect); resized(); } @@ -631,11 +733,17 @@ void CrystalizerEQAudioProcessorEditor::resized() - Typography::applyToLabel(titleLabel, Typography::Style::Display, 1.f); + /*Typography::applyToLabel(titleLabel, Typography::Style::Display, 1.f); titleLabel.setColour(juce::Label::textColourId, Colours::ACCENTCOLOUR); titleLabel.setJustificationType(juce::Justification::centred); - titleLabel.setBounds (getLocalBounds().removeFromTop(20)); + titleLabel.setBounds (getLocalBounds().removeFromTop(20));*/ + auto pluginArea = getLocalBounds(); + scalePluginWindow(pluginArea); + setupMainGrid(pluginArea); + setupHeader(); + setupBody(); + setupFooter(); //TODO: PLACE ALL KNOBS AND BUILD FUNCTIONS FOR THEIR DESIGN /*i = place(i, &testNoiseLabel, &testNoiseSlider); @@ -696,6 +804,160 @@ void CrystalizerEQAudioProcessorEditor::resized() } +void CrystalizerEQAudioProcessorEditor::scalePluginWindow(juce::Rectangle area) { + + if (area.getWidth() < 520) Spacing::setUiScale(Spacing::uiScaleMode::XS); + else if (area.getWidth() < 720) Spacing::setUiScale(Spacing::uiScaleMode::S); + else if (area.getWidth() < 1024) Spacing::setUiScale(Spacing::uiScaleMode::M); + else if (area.getWidth() < 1366) Spacing::setUiScale(Spacing::uiScaleMode::L); + else Spacing::setUiScale(Spacing::uiScaleMode::XL); +} + +void CrystalizerEQAudioProcessorEditor::setupMainGrid(juce::Rectangle area) { + const float headerHeight = static_cast(getHeight()) * 0.1f; + const float footerHeight = static_cast(getHeight()) * 0.15f; + + Layout::GridSpec spec { + /* cols */ { Layout::fr(1) }, // eine Spalte, füllt Breite + /* rows */ { Layout::pxTrack(headerHeight), Layout::fr(1), Layout::pxTrack(footerHeight) }, // Header / Body / Footer + /* colGap */ Spacing::SizeMode::S, + /* rowGap */ Spacing::SizeMode::S, + /* pad */ Layout::padding(Spacing::SizeMode::S) + }; + Layout::grid(area, spec, { &headerBar, &mainPanel, &footerBar }); + +} + +void CrystalizerEQAudioProcessorEditor::setupHeader() { + + const auto bounds = headerBar.getLocalBounds(); + + const float presetAreaWidth = static_cast(bounds.getWidth()) * 0.5f; + + Layout::GridSpec headerSpec{ + /* cols */ { Layout::fr(1), Layout::pxTrack(presetAreaWidth), Layout::fr(1) }, + /* rows */ { Layout::fr(1) }, + /* colGap */ Spacing::SizeMode::XS, + /* rowGap */ Spacing::SizeMode::XS, + /* pad */ Layout::padding(Spacing::SizeMode::XS) + }; + Layout::grid(bounds, headerSpec, { + Layout::area(titleLabel, 1, 1, 2, 2), + Layout::area(presetArea, 1, 2, 2, 3) }); + + const auto presetAreaBounds = presetArea.getLocalBounds(); + const auto presetBoxWidth = static_cast(presetArea.getWidth()); + const auto presetBoxHeight = static_cast(presetArea.getHeight()); + + + Layout::GridSpec presetSpec{ + /* cols */ { Layout::fr(1), Layout::pxTrack(presetBoxWidth * 0.5f), Layout::fr(1)}, + /* rows */ { Layout::pxTrack(presetBoxHeight * 0.25f), Layout::pxTrack(presetBoxHeight * 0.25f)}, + /* colGap */ Spacing::SizeMode::XS, + /* rowGap */ Spacing::SizeMode::XS, + /* pad */ Layout::padding(Spacing::SizeMode::S) + }; + Layout::grid(presetAreaBounds, presetSpec, { + // Label über beide Spalten (row1, col1..2) + Layout::area(presetBoxLabel, 1, 2, 2, 3), + // Box unten links (row2, col1) + Layout::area(presetBox, 2, 2, 3, 3), + Layout::area(resetButton, 2, 1, 2, 2), + // Menütaste unten rechts (row2, col2) + Layout::area(presetMenuButton, 2, 3, 3, 4), + }); + + +} + + + +void CrystalizerEQAudioProcessorEditor::setupBody() { + const auto bounds = mainPanel.getLocalBounds(); + + const auto bodyHeight = static_cast(bounds.getHeight()); + const auto bodyWidth = static_cast(bounds.getWidth()); + const auto bodyColWidth = bodyWidth / 5.0f; + + Layout::GridSpec bodySpec{ + /* cols */ { Layout::fr(1), Layout::pxTrack(bodyColWidth), Layout::pxTrack(bodyColWidth), Layout::pxTrack(bodyColWidth), Layout::fr(1) }, + /* rows */ { Layout::fr(1), Layout::fr(1) }, + /* colGap */ Spacing::SizeMode::XS, + /* rowGap */ Spacing::SizeMode::XS, + /* pad */ Layout::padding(Spacing::SizeMode::XS) + }; + Layout::grid(bounds, bodySpec, { + Layout::area(analyzerArea, 1, 2, 2, 5), + Layout::area(filterArea, 2, 1, 3, 6) + }); + + const auto analyzerAreaBounds = analyzerArea.getLocalBounds(); + const auto analyzerAreaWidth = static_cast(analyzerArea.getWidth()); + const auto analyzerAreaHeight = static_cast(analyzerArea.getHeight()); + + const auto filterAreaBounds = filterArea.getLocalBounds(); + const auto filterAreaWidth = static_cast(filterArea.getWidth()); + const auto filterAreaHeight = static_cast(filterArea.getHeight()); + const auto filterColWidth = filterAreaWidth * 0.2f; + + + + Layout::GridSpec filterSpec{ + /* cols */ { Layout::fr(1), Layout::pxTrack(filterColWidth), Layout::pxTrack(filterColWidth), Layout::pxTrack(filterColWidth), Layout::fr(1) }, + /* rows */ { Layout::fr(1)}, + /* colGap */ Spacing::SizeMode::XS, + /* rowGap */ Spacing::SizeMode::XS, + /* pad */ Layout::padding(Spacing::SizeMode::S) + }; + Layout::grid(filterAreaBounds, filterSpec, { + Layout::area(lowFilterArea, 1, 1, 2, 2), + Layout::area(lowMidFilterArea, 1, 2, 2, 3), + Layout::area(midFilterArea, 1, 3, 2, 4), + Layout::area(highMidFilterArea, 1, 4, 2, 5), + Layout::area(highFilterArea, 1, 5, 2, 6), + + }); + + setupLowBandLayout(); + + +} + +void CrystalizerEQAudioProcessorEditor::setupLowBandLayout() { + const auto bounds = lowFilterArea.getLocalBounds(); + const auto areaWidth = static_cast(bounds.getWidth()); + const auto areaHeight = static_cast(bounds.getHeight()); + const auto knobColWidth = areaWidth / 3.0f; + const auto knobRowHeight = areaHeight / 3.0f; + + Layout::GridSpec lowBandSpec{ + /* cols */ { Layout::fr(1), Layout::pxTrack(knobColWidth), Layout::fr(1) }, + /* rows */ { Layout::fr(1), Layout::pxTrack(knobRowHeight * 1.25f), Layout::fr(1)}, + /* colGap */ Spacing::SizeMode::XS, + /* rowGap */ Spacing::SizeMode::XS, + /* pad */ Layout::padding(Spacing::SizeMode::XS) + }; + Layout::grid(bounds, lowBandSpec, { + Layout::area(lowBandFreqLabel, 1, 1, 2, 2), + Layout::area(lowBandGainLabel, 1, 2, 2, 3), + Layout::area(lowBandQLabel, 1, 3, 2, 4), + Layout::area(lowBandFreqSlider, 2, 1, 3, 2), + Layout::area(lowBandGainSlider, 2, 2, 3, 3), + Layout::area(lowBandQSlider, 2, 3, 3, 4), + Layout::area(lowBandModeBox, 3, 1, 4, 2), + Layout::area(lowBandSlopeLabel, 3, 2, 4, 3), + Layout::area(lowBandSlopeSlider, 3, 3, 4, 4), + + }); +} + + +void CrystalizerEQAudioProcessorEditor::setupFooter() { + +} + + + void SpectrumAnalyzer::processSamples() { auto samples = audioFIFO.sendSamplesToEditor(); diff --git a/CrystalizerEQ/PluginEditor.h b/CrystalizerEQ/PluginEditor.h index 2dff5f5..8cd2a76 100644 --- a/CrystalizerEQ/PluginEditor.h +++ b/CrystalizerEQ/PluginEditor.h @@ -189,7 +189,33 @@ private: SpectrumAnalyzer spectrumAnalyzer; - juce::Rectangle analyzerArea; + juce::Rectangle analyzerRect; + + Component headerBar; + Component mainPanel; + Component footerBar; + + Component presetArea; + + Component analyzerArea; + + Component filterArea; + Component lowFilterArea; + Component lowMidFilterArea; + Component midFilterArea; + Component highMidFilterArea; + Component highFilterArea; + + + + void scalePluginWindow(juce::Rectangle area); + void setupMainGrid(juce::Rectangle area); + + void setupLowBandLayout(); + + void setupHeader(); + void setupBody(); + void setupFooter(); diff --git a/CrystalizerEQ/cmake-build-debug-visual-studio/Testing/Temporary/LastTest.log b/CrystalizerEQ/cmake-build-debug-visual-studio/Testing/Temporary/LastTest.log index 76e8af7..05c9cef 100644 --- a/CrystalizerEQ/cmake-build-debug-visual-studio/Testing/Temporary/LastTest.log +++ b/CrystalizerEQ/cmake-build-debug-visual-studio/Testing/Temporary/LastTest.log @@ -1,3 +1,3 @@ -Start testing: Oct 27 18:58 Mitteleuropäische Zeit +Start testing: Oct 30 20:59 Mitteleuropäische Zeit ---------------------------------------------------------- -End testing: Oct 27 18:58 Mitteleuropäische Zeit +End testing: Oct 30 20:59 Mitteleuropäische Zeit