Skip to content

Commit

Permalink
First proto
Browse files Browse the repository at this point in the history
  • Loading branch information
kmolcard committed Feb 15, 2024
1 parent 0159303 commit 8e5dab2
Show file tree
Hide file tree
Showing 8 changed files with 974 additions and 106 deletions.
61 changes: 51 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ include(PamplejuceMacOS)
# This is the internal name of the project and the name of JUCE's shared code target
# Note: This cannot have spaces (it may be 2024, but you can't have it all!)
# Worry not, JUCE's PRODUCT_NAME can have spaces (and is what DAWs display)
set(PROJECT_NAME "Pamplejuce")
set(PROJECT_NAME "BWSynth")

# Worry not, JUCE's PRODUCT_NAME can have spaces (and is what DAWs will display)
# You can also just have it be the same thing as PROJECT_NAME
# You may want to append the major version on the end of this (and PROJECT_NAME) ala:
# set(PROJECT_NAME "MyPlugin_v${MAJOR_VERSION}")
# Doing so enables major versions to show up in IDEs and DAWs as separate plugins
# allowing you to change parameters and behavior without breaking existing user projects
set(PRODUCT_NAME "Pamplejuce Demo")
set(PRODUCT_NAME "BW Synth")

# Change me! Used for the MacOS bundle name and Installers
set(COMPANY_NAME "Pamplejuce Company")
set(COMPANY_NAME "KM Audio")

# Change me! Used for the MacOS bundle identifier (and signing)
set(BUNDLE_ID "com.pamplejuce.pamplejuce")
set(BUNDLE_ID "com.kmaudio.bwsynth")

# Change me! Set the plugin formats you want built
# Valid choices: AAX Unity VST VST3 AU AUv3 Standalone
Expand All @@ -47,6 +47,33 @@ add_subdirectory(JUCE)

# Add any other modules you want modules here, before the juce_add_plugin call
# juce_add_module(modules/my_module)
juce_add_module("modules/melatonin_blur")



set(BW_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/brickworks)
set(BW_INCLUDE_DIR
${BW_ROOT_DIR}/
${BW_ROOT_DIR}/include
${BW_ROOT_DIR}/examples/common/vst3/
)

set(BW_SRC
${BW_ROOT_DIR}/examples/synthpp_poly/src/bw_example_synthpp_poly.cpp
${BW_ROOT_DIR}/examples/synthpp_poly/src/bw_example_synthpp_poly.h
)

add_library(bw_examples STATIC ${BW_SRC})
target_compile_features(bw_examples PUBLIC cxx_std_20)

# Create the static library
# Set include directories for the library
target_include_directories(bw_examples
PRIVATE
${BW_INCLUDE_DIR}
)

add_subdirectory(chowdsp_utils)

# This adds the melatonin inspector module
add_subdirectory (modules/melatonin_inspector)
Expand All @@ -66,19 +93,22 @@ juce_add_plugin("${PROJECT_NAME}"
# Change me!
# A four-character plugin id
# First character MUST be uppercase for AU formats
PLUGIN_MANUFACTURER_CODE Pamp
PLUGIN_MANUFACTURER_CODE KMau

# Change me!
# A unique four-character plugin id
# Note: this must have at least one upper-case character
PLUGIN_CODE P001
PLUGIN_CODE BwSy
FORMATS "${FORMATS}"

# The name of your final executable
# This is how it's listed in the DAW
# This can be different from PROJECT_NAME and can have spaces!
# You might want to use v${MAJOR_VERSION} here once you go to v2...
PRODUCT_NAME "${PRODUCT_NAME}")
PRODUCT_NAME "${PRODUCT_NAME}"

IS_SYNTH TRUE
)

# This lets us use our code in both the JUCE targets and our Test target
# Without running into ODR violations
Expand Down Expand Up @@ -112,14 +142,14 @@ target_compile_definitions(SharedCode
JUCE_VST3_CAN_REPLACE_VST2=0

# Uncomment if you are paying for a an Indie/Pro license or releasing under GPLv3
# JUCE_DISPLAY_SPLASH_SCREEN=0
JUCE_DISPLAY_SPLASH_SCREEN=0

# lets the app known if we're Debug or Release
CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
VERSION="${CURRENT_VERSION}"

# JucePlugin_Name is for some reason doesn't use the nicer PRODUCT_NAME
PRODUCT_NAME_WITHOUT_VERSION="Pamplejuce"
PRODUCT_NAME_WITHOUT_VERSION="BW Synth"
)

# Link to any other modules you added (with juce_add_module) here!
Expand All @@ -131,14 +161,25 @@ target_link_libraries(SharedCode
INTERFACE
Assets
melatonin_inspector
melatonin_blur
juce_audio_utils
juce_audio_processors
juce_dsp
juce_gui_basics
juce_gui_extra
juce::juce_recommended_config_flags
juce::juce_recommended_lto_flags
juce::juce_recommended_warning_flags)
juce::juce_recommended_warning_flags
bw_examples
chowdsp::chowdsp_plugin_state
)


target_include_directories(${PROJECT_NAME}
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/modules/"
"${BW_INCLUDE_DIR}"
)

# Link the JUCE plugin targets our SharedCode target
target_link_libraries("${PROJECT_NAME}" PRIVATE SharedCode)
Expand Down
161 changes: 161 additions & 0 deletions source/KMOLookAndFeel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#include "KMOLookAndFeel.h"

#include <melatonin_blur/melatonin_blur.h>

namespace kmo
{
void KMOLookAndFeel::drawRotarySlider (juce::Graphics& g, int x, int y, int width, int height, float sliderPos, const float rotaryStartAngle, const float rotaryEndAngle, juce::Slider& slider)
{
auto outline = slider.findColour (juce::Slider::rotarySliderOutlineColourId);
auto fill = slider.findColour (juce::Slider::rotarySliderFillColourId);

auto bounds = juce::Rectangle<int> (x, y, width, height).toFloat().reduced (10);

auto radius = juce::jmin (bounds.getWidth(), bounds.getHeight()) / 2.0f;
auto toAngle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
auto lineW = juce::jmin (8.0f, radius * 0.5f);
auto arcRadius = radius - lineW * 0.5f;

juce::Path backgroundArc;
backgroundArc.addCentredArc (bounds.getCentreX(),
bounds.getCentreY(),
arcRadius,
arcRadius,
0.0f,
rotaryStartAngle,
rotaryEndAngle,
true);

g.setColour (outline);
g.strokePath (backgroundArc, juce::PathStrokeType (lineW, juce::PathStrokeType::curved, juce::PathStrokeType::rounded));

if (slider.isEnabled())
{
juce::Path valueArc;
valueArc.addCentredArc (bounds.getCentreX(),
bounds.getCentreY(),
arcRadius,
arcRadius,
0.0f,
rotaryStartAngle,
toAngle,
true);

g.setColour (fill);
g.strokePath (valueArc, juce::PathStrokeType (lineW, juce::PathStrokeType::curved, juce::PathStrokeType::rounded));
}

auto thumbWidth = lineW * 2.0f;
juce::Point<float> thumbPoint (bounds.getCentreX() + arcRadius * std::cos (toAngle - juce::MathConstants<float>::halfPi),
bounds.getCentreY() + arcRadius * std::sin (toAngle - juce::MathConstants<float>::halfPi));

const auto& c { slider.findColour (juce::Slider::thumbColourId) };
g.setColour (c);

juce::Path myValueTrack;
auto e = juce::Rectangle<float> (thumbWidth, thumbWidth).withCentre (thumbPoint);
myValueTrack.addEllipse (e);
melatonin::DropShadow shadow = { { c, 8, { 0, 0 } } };
shadow.render (g, myValueTrack);
g.fillEllipse (e);
g.setColour (juce::Colours::black);
g.drawEllipse (e, 1.f);
}

void KMOLookAndFeel::drawLinearSlider (juce::Graphics& g, int x, int y, int width, int height, float sliderPos, float minSliderPos, float maxSliderPos, const juce::Slider::SliderStyle style, juce::Slider& slider)
{
if (slider.isBar())
{
g.setColour (slider.findColour (juce::Slider::trackColourId));
g.fillRect (slider.isHorizontal() ? juce::Rectangle<float> (static_cast<float> (x), (float) y + 0.5f, sliderPos - (float) x, (float) height - 1.0f)
: juce::Rectangle<float> ((float) x + 0.5f, sliderPos, (float) width - 1.0f, (float) y + ((float) height - sliderPos)));

drawLinearSliderOutline (g, x, y, width, height, style, slider);
}
else
{
auto isTwoVal = (style == juce::Slider::SliderStyle::TwoValueVertical || style == juce::Slider::SliderStyle::TwoValueHorizontal);
auto isThreeVal = (style == juce::Slider::SliderStyle::ThreeValueVertical || style == juce::Slider::SliderStyle::ThreeValueHorizontal);

auto trackWidth = juce::jmin (6.0f, slider.isHorizontal() ? (float) height * 0.25f : (float) width * 0.25f);

juce::Point<float> startPoint (slider.isHorizontal() ? (float) x : (float) x + (float) width * 0.5f,
slider.isHorizontal() ? (float) y + (float) height * 0.5f : (float) (height + y));

juce::Point<float> endPoint (slider.isHorizontal() ? (float) (width + x) : startPoint.x,
slider.isHorizontal() ? startPoint.y : (float) y);

juce::Path backgroundTrack;
backgroundTrack.startNewSubPath (startPoint);
backgroundTrack.lineTo (endPoint);
g.setColour (slider.findColour (juce::Slider::backgroundColourId));
g.strokePath (backgroundTrack, { trackWidth, juce::PathStrokeType::curved, juce::PathStrokeType::rounded });

juce::Path valueTrack;
juce::Point<float> minPoint, maxPoint, thumbPoint;

if (isTwoVal || isThreeVal)
{
minPoint = { slider.isHorizontal() ? minSliderPos : (float) width * 0.5f,
slider.isHorizontal() ? (float) height * 0.5f : minSliderPos };

if (isThreeVal)
thumbPoint = { slider.isHorizontal() ? sliderPos : (float) width * 0.5f,
slider.isHorizontal() ? (float) height * 0.5f : sliderPos };

maxPoint = { slider.isHorizontal() ? maxSliderPos : (float) width * 0.5f,
slider.isHorizontal() ? (float) height * 0.5f : maxSliderPos };
}
else
{
auto kx = slider.isHorizontal() ? sliderPos : ((float) x + (float) width * 0.5f);
auto ky = slider.isHorizontal() ? ((float) y + (float) height * 0.5f) : sliderPos;

minPoint = startPoint;
maxPoint = { kx, ky };
}

auto thumbWidth = getSliderThumbRadius (slider);

valueTrack.startNewSubPath (minPoint);
valueTrack.lineTo (isThreeVal ? thumbPoint : maxPoint);
g.setColour (slider.findColour (juce::Slider::trackColourId));
g.strokePath (valueTrack, { trackWidth, juce::PathStrokeType::curved, juce::PathStrokeType::rounded });

if (!isTwoVal)
{
juce::Path myValueTrack;
auto e = juce::Rectangle<float> (static_cast<float> (thumbWidth), static_cast<float> (thumbWidth)).withCentre (isThreeVal ? thumbPoint : maxPoint);
auto c { slider.findColour (juce::Slider::thumbColourId) };
myValueTrack.addEllipse (e);
melatonin::DropShadow shadow = { { c, 8, { 0, 0 } } };
shadow.render (g, myValueTrack);

g.setColour (c);
g.fillEllipse (e);
}

if (isTwoVal || isThreeVal)
{
auto sr = juce::jmin (trackWidth, (slider.isHorizontal() ? (float) height : (float) width) * 0.4f);
auto pointerColour = slider.findColour (juce::Slider::thumbColourId);

if (slider.isHorizontal())
{
drawPointer (g, minSliderPos - sr, juce::jmax (0.0f, (float) y + (float) height * 0.5f - trackWidth * 2.0f), trackWidth * 2.0f, pointerColour, 2);

drawPointer (g, maxSliderPos - trackWidth, juce::jmin ((float) (y + height) - trackWidth * 2.0f, (float) y + (float) height * 0.5f), trackWidth * 2.0f, pointerColour, 4);
}
else
{
drawPointer (g, juce::jmax (0.0f, (float) x + (float) width * 0.5f - trackWidth * 2.0f), minSliderPos - trackWidth, trackWidth * 2.0f, pointerColour, 1);

drawPointer (g, juce::jmin ((float) (x + width) - trackWidth * 2.0f, (float) x + (float) width * 0.5f), maxSliderPos - sr, trackWidth * 2.0f, pointerColour, 3);
}
}

if (slider.isBar())
drawLinearSliderOutline (g, x, y, width, height, style, slider);
}
}
}
14 changes: 14 additions & 0 deletions source/KMOLookAndFeel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <juce_gui_basics/juce_gui_basics.h>

namespace kmo
{

class KMOLookAndFeel : public juce::LookAndFeel_V4
{
void drawRotarySlider (juce::Graphics& g, int x, int y, int width, int height, float sliderPos, const float rotaryStartAngle, const float rotaryEndAngle, juce::Slider& slider);
void drawLinearSlider (juce::Graphics& g, int x, int y, int width, int height, float sliderPos, float minSliderPos, float maxSliderPos, const juce::Slider::SliderStyle style, juce::Slider& slider);
};

}
Loading

0 comments on commit 8e5dab2

Please sign in to comment.