Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ endif()

add_library(${PROJECT_NAME} STATIC
src/sst/jucegui/components/ComponentBase.cpp
src/sst/jucegui/components/CompactPlot.cpp
src/sst/jucegui/components/ContinuousParamEditor.cpp
src/sst/jucegui/components/DiscreteParamEditor.cpp
src/sst/jucegui/components/DiscreteParamMenuBuilder.cpp
Expand Down
76 changes: 76 additions & 0 deletions include/sst/jucegui/components/CompactPlot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* sst-jucegui - an open source library of juce widgets
* built by Surge Synth Team.
*
* Copyright 2023-2024, various authors, as described in the GitHub
* transaction log.
*
* sst-jucegui is released under the MIT license, as described
* by "LICENSE.md" in this repository. This means you may use this
* in commercial software if you are a JUCE Licensee. If you use JUCE
* in the open source / GPL3 context, your combined work must be
* released under GPL3.
*
* All source in sst-jucegui available at
* https://github.com/surge-synthesizer/sst-jucegui
*/

#ifndef INCLUDE_SST_JUCEGUI_COMPONENTS_COMPACTPLOT_H
#define INCLUDE_SST_JUCEGUI_COMPONENTS_COMPACTPLOT_H

#include <utility>
#include <vector>

#include "sst/jucegui/style/StyleAndSettingsConsumer.h"
#include "sst/jucegui/style/StyleSheet.h"
#include "BaseStyles.h"

namespace sst::jucegui::components
{
struct CompactPlot : public juce::Component, public style::StyleConsumer
{
struct Styles
{
using sclass = style::StyleSheet::Class;
using sprop = style::StyleSheet::Property;
static constexpr sclass styleClass{"compactplot"};

PROP(plotAxis);
PROP(plotLine);
PROP(plotGradStart);
PROP(plotGradEnd);

static void initialize()
{
style::StyleSheet::addClass(styleClass)
.withProperty(plotAxis)
.withProperty(plotLine)
.withProperty(plotGradStart)
.withProperty(plotGradEnd);
}
};

CompactPlot() : style::StyleConsumer(Styles::styleClass) {}
~CompactPlot() {}

virtual bool curvePathIsValid() const = 0;

using point_t = std::pair<float, float>;
using plotData_t = std::vector<point_t>;
virtual void recalculateCurvePath(plotData_t &into) = 0;

using axisBounds_t = std::pair<float, float>;
virtual axisBounds_t getXAxisBounds() const { return {0, 1}; }
virtual axisBounds_t getYAxisBounds() const { return {-1, 1}; }
virtual bool isYAxisFromZero() const { return getYAxisBounds().first == 0; }

void paint(juce::Graphics &g) override;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CompactPlot);

protected:
juce::Path curvePath, positiveCurvePath, negativeCurvePath;
plotData_t plotData;
};
} // namespace sst::jucegui::components
#endif // COMPACTPLOT_H
86 changes: 86 additions & 0 deletions src/sst/jucegui/components/CompactPlot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* sst-jucegui - an open source library of juce widgets
* built by Surge Synth Team.
*
* Copyright 2023-2024, various authors, as described in the GitHub
* transaction log.
*
* sst-jucegui is released under the MIT license, as described
* by "LICENSE.md" in this repository. This means you may use this
* in commercial software if you are a JUCE Licensee. If you use JUCE
* in the open source / GPL3 context, your combined work must be
* released under GPL3.
*
* All source in sst-jucegui available at
* https://github.com/surge-synthesizer/sst-jucegui
*/

#include "sst/jucegui/components/CompactPlot.h"

namespace sst::jucegui::components
{
void CompactPlot::paint(juce::Graphics &g)
{
auto cl = 1.0f;
if (!isYAxisFromZero())
{
auto yb = getYAxisBounds();
cl = yb.second / (-yb.first + yb.second);
}

if (curvePath.isEmpty() || plotData.empty() || !curvePathIsValid())
{
plotData.clear();
recalculateCurvePath(plotData);

curvePath.clear();
positiveCurvePath.clear();
negativeCurvePath.clear();

positiveCurvePath.startNewSubPath(0, cl);
negativeCurvePath.startNewSubPath(0, cl);

bool first{true};
for (const auto &[x, y] : plotData)
{
if (first)
{
curvePath.startNewSubPath(x, y);
first = false;
}
else
{
curvePath.lineTo(x, y);
}
positiveCurvePath.lineTo(x, std::min(y, cl));
negativeCurvePath.lineTo(x, std::max(y, cl));
}
positiveCurvePath.lineTo(1, cl);
positiveCurvePath.closeSubPath();
negativeCurvePath.lineTo(1, cl);
negativeCurvePath.closeSubPath();
}

auto axisColor = getColour(Styles::plotAxis);
auto gradStart = getColour(Styles::plotGradStart);
auto gradEnd = getColour(Styles::plotGradEnd);
auto plotStroke = getColour(Styles::plotLine);

auto lg = juce::ColourGradient::vertical(gradStart, 0, gradEnd, cl * getHeight());
g.setGradientFill(lg);
g.fillPath(positiveCurvePath, juce::AffineTransform().scaled(getWidth(), getHeight()));

auto lg2 = juce::ColourGradient::vertical(gradEnd, cl * getHeight(), gradStart, getHeight());
g.setGradientFill(lg2);
g.fillPath(negativeCurvePath, juce::AffineTransform().scaled(getWidth(), getHeight()));

g.setColour(axisColor);
g.drawLine(0, 0, 0, getHeight(), 1);
g.drawLine(0, cl * getHeight(), getWidth(), cl * getHeight(), 1);

g.setColour(plotStroke);
g.strokePath(curvePath, juce::PathStrokeType(1.0),
juce::AffineTransform().scaled(getWidth(), getHeight()));
}

} // namespace sst::jucegui::components
20 changes: 20 additions & 0 deletions src/sst/jucegui/style/StyleSheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <sst/jucegui/components/Viewport.h>
#include <sst/jucegui/components/TabbedComponent.h>
#include <sst/jucegui/components/TypeInOverlay.h>
#include <sst/jucegui/components/CompactPlot.h>
#include <sst/jucegui/util/DebugHelpers.h>

#include <cassert>
Expand Down Expand Up @@ -381,6 +382,15 @@ struct DarkSheet : public StyleSheetBuiltInImpl
getFont(components::base_styles::BaseLabel::styleClass,
components::base_styles::BaseLabel::labelfont));
}

{
using n = components::CompactPlot::Styles;
setColour(n::styleClass, n::plotAxis, juce::Colour(0x50, 0x50, 0x50));
setColour(n::styleClass, n::plotGradStart, juce::Colour(0xFF, 0x90, 0x00));
setColour(n::styleClass, n::plotGradEnd,
juce::Colour(0xFF, 0x90, 0x00).withAlpha(0.2f));
setColour(n::styleClass, n::plotLine, juce::Colours::white);
}
}
};

Expand Down Expand Up @@ -528,6 +538,15 @@ struct LightSheet : public StyleSheetBuiltInImpl
getFont(components::base_styles::BaseLabel::styleClass,
components::base_styles::BaseLabel::labelfont));
}

{
using n = components::CompactPlot::Styles;
setColour(n::styleClass, n::plotAxis, juce::Colour(0x50, 0x50, 0x50));
setColour(n::styleClass, n::plotGradStart, juce::Colour(0xFF, 0x90, 0x00));
setColour(n::styleClass, n::plotGradEnd,
juce::Colour(0xFF, 0x90, 0x00).withAlpha(0.2f));
setColour(n::styleClass, n::plotLine, juce::Colours::white);
}
}
};

Expand Down Expand Up @@ -651,6 +670,7 @@ void StyleSheet::initializeStyleSheets(std::function<void()> userClassInitialize
n::TextEditor::Styles::initialize();

n::TabularizedTreeViewer::Styles::initialize();
n::CompactPlot::Styles::initialize();
}

userClassInitializers();
Expand Down