35 m_multiSlider = std::make_unique<Mema::TwoDFieldMultisliderComponent>();
37 changeInputPosition(channel, value.relXPos, value.relYPos, sharpness, layer.has_value() ? layer.value() : 0);
39 m_multiSlider->onInputToOutputStatesChanged = [=](
const std::map<std::uint16_t, std::map<std::uint16_t, bool>>& inputToOutputStates) {
44 m_multiSlider->onInputToOutputValuesChanged = [=](
const std::map<std::uint16_t, std::map<std::uint16_t, float>>& inputToOutputValues) {
49 m_multiSlider->onInputSelected = [=](std::uint16_t channel) {
52 addAndMakeVisible(m_multiSlider.get());
54 m_positionMapper = std::make_unique<InputPositionMapper>();
55 m_positionMapper->onInputPositionMapped = [=](std::uint16_t channel,
const std::map<juce::AudioChannelSet::ChannelType, float>& channelToOutputsDists) {
58 m_positionMapper->getAngleForChannelType = [=](juce::AudioChannelSet::ChannelType channelType) {
60 return m_multiSlider->getAngleForChannelTypeInCurrentConfiguration(channelType);
65 m_admOsController = std::make_unique<ADMOSController>();
66 m_admOsController->onParameterChanged = [=](
int objNum, std::uint16_t objType) {
70 m_horizontalScrollContainerComponent = std::make_unique<juce::Component>();
71 m_horizontalScrollViewport = std::make_unique<juce::Viewport>();
72 m_horizontalScrollViewport->setViewedComponent(m_horizontalScrollContainerComponent.get(),
false);
73 addAndMakeVisible(m_horizontalScrollViewport.get());
75 m_inputControlsGrid = std::make_unique<juce::Grid>();
76 m_inputControlsGrid->setGap(juce::Grid::Px(
s_gap));
100 if (m_inputControlsGrid)
101 m_inputControlsGrid->performLayout({ 0, 0, currentInputsWidth, ctrlsSize -
s_scrollbarsize });
103 m_horizontalScrollContainerComponent->setBounds({ 0, 0, currentInputsWidth, ctrlsSize -
s_scrollbarsize });
104 m_horizontalScrollViewport->setBounds(getLocalBounds().removeFromTop(ctrlsSize).removeFromRight(getWidth() - ctrlsSize));
106 auto panningBounds = getLocalBounds();
107 panningBounds.removeFromTop(ctrlsSize);
109 auto boundsAspect = panningBounds.toFloat().getAspectRatio();
110 auto fieldAspect = m_multiSlider->getRequiredAspectRatio();
111 if (boundsAspect >= 1 / fieldAspect)
114 auto multiSliderBounds = juce::Rectangle<int>(
int(panningBounds.getHeight() / fieldAspect), panningBounds.getHeight()).withCentre(panningBounds.getCentre());
116 m_multiSlider->setBounds(multiSliderBounds);
121 auto multiSliderBounds = juce::Rectangle<int>(panningBounds.getWidth(),
int(panningBounds.getWidth() * fieldAspect)).withCentre(panningBounds.getCentre());
123 m_multiSlider->setBounds(multiSliderBounds);
196 DBG(juce::String(__FUNCTION__) <<
" handle n" << objNum <<
" t" << admObjType);
198 jassert(m_admOsController);
199 if (!m_admOsController)
201 jassert(m_multiSlider);
217 changeInputPosition(std::uint16_t(objNum), xVal, std::nullopt, std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
230 changeInputPosition(std::uint16_t(objNum), std::nullopt, yVal, std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
242 changeInputPosition(std::uint16_t(objNum), std::nullopt, std::nullopt, std::nullopt, (zVal > 0.5f ? TwoDFieldMultisliderComponent::ChannelLayer::PositionedHeight : TwoDFieldMultisliderComponent::ChannelLayer::Positioned), juce::NotificationType::sendNotification);
256 changeInputPosition(std::uint16_t(objNum), std::get<0>(xyVals), std::get<1>(xyVals), std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
269 changeInputPosition(std::uint16_t(objNum), std::get<0>(xyzVals), std::get<1>(xyzVals), std::nullopt, (std::get<2>(xyzVals) > 0.5f ? TwoDFieldMultisliderComponent::ChannelLayer::PositionedHeight : TwoDFieldMultisliderComponent::ChannelLayer::Positioned), juce::NotificationType::sendNotification);
277 changeInputPosition(std::uint16_t(objNum), std::nullopt, std::nullopt, 1.0f - widthVal, std::nullopt, juce::NotificationType::sendNotification);
298 if (ioCount.first != m_inputSelectButtons.size() || ioCount.first != m_inputMuteButtons.size() || force)
300 auto templateColums = juce::Array<juce::Grid::TrackInfo>();
301 for (
auto in = 0; in < ioCount.first; in++)
302 templateColums.add(juce::Grid::TrackInfo(juce::Grid::Px(
m_controlsSize)));
304 m_inputMuteButtons.resize(ioCount.first);
305 m_inputSelectButtons.resize(ioCount.first);
306 m_inputControlsGrid->items.clear();
307 m_inputControlsGrid->templateRows = { juce::Grid::TrackInfo(juce::Grid::Fr(1)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) };
308 m_inputControlsGrid->templateColumns = templateColums;
310 for (
auto i = 0; i < ioCount.first; i++)
312 auto in = std::uint16_t(i + 1);
313 m_inputSelectButtons.at(i) = std::make_unique<juce::TextButton>(
"In " + juce::String(in));
314 m_inputSelectButtons.at(i)->setClickingTogglesState(
true);
315 m_inputSelectButtons.at(i)->setColour(juce::TextButton::ColourIds::buttonOnColourId, getLookAndFeel().findColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId));
316 m_inputSelectButtons.at(i)->onClick = [
this, i] {
317 if (m_inputSelectButtons.size() > i)
319 auto in = std::uint16_t(i + 1);
320 if (m_inputSelectButtons.at(i)->getToggleState())
328 m_horizontalScrollContainerComponent->addAndMakeVisible(m_inputSelectButtons.at(i).get());
329 m_inputControlsGrid->items.add(juce::GridItem(m_inputSelectButtons.at(i).get()));
331 for (
auto i = 0; i < ioCount.first; i++)
333 auto in = std::uint16_t(i + 1);
334 m_inputMuteButtons.at(i) = std::make_unique<juce::TextButton>(
"M");
335 m_inputMuteButtons.at(i)->setClickingTogglesState(
true);
337 m_inputMuteButtons.at(i)->setColour(juce::TextButton::ColourIds::buttonOnColourId, juce::Colours::red);
338 m_inputMuteButtons.at(i)->onClick = [
this, i] {
339 auto inputMuteStates = std::map<std::uint16_t, bool>();
340 auto in = std::uint16_t(i + 1);
341 inputMuteStates[in] = m_inputMuteButtons.at(i)->getToggleState();
345 if (m_admOsController)
348 m_horizontalScrollContainerComponent->addAndMakeVisible(m_inputMuteButtons.at(i).get());
349 m_inputControlsGrid->items.add(juce::GridItem(m_inputMuteButtons.at(i).get()));
386 auto oldChannel = m_currentInputChannel;
387 m_currentInputChannel = channel;
388 if (oldChannel != channel)
392 for (
auto i = 0; i < ioCount.first; i++)
394 auto in = std::uint16_t(i + 1);
395 auto state = channel == in;
396 if (
nullptr != m_inputSelectButtons.at(i))
397 m_inputSelectButtons.at(i)->setToggleState(state, juce::dontSendNotification);
398 if (
nullptr != m_multiSlider)
399 m_multiSlider->selectInput(in, state);
403void PanningControlComponent::changeInputPosition(std::uint16_t channel, std::optional<float> xValOpt, std::optional<float> yValOpt, std::optional<float> sharpnessOpt, std::optional<int> layerOpt, juce::NotificationType notification)
406 if (xValOpt.has_value())
407 xVal = xValOpt.value();
408 else if (m_admOsController)
412 if (yValOpt.has_value())
413 yVal = yValOpt.value();
414 else if (m_admOsController)
417 float sharpnessVal = 0.0f;
418 if (sharpnessOpt.has_value())
419 sharpnessVal = sharpnessOpt.value();
420 else if (m_admOsController)
424 if (layerOpt.has_value())
425 layerVal = layerOpt.value();
426 else if (m_admOsController)
429 layerVal = zVal > 0.5f ? TwoDFieldMultisliderComponent::ChannelLayer::PositionedHeight : TwoDFieldMultisliderComponent::ChannelLayer::Positioned;
432 DBG(juce::String(__FUNCTION__) <<
" new pos: " <<
int(channel) <<
" " << xVal <<
"," << yVal <<
"(" << sharpnessVal <<
" / " << layerVal <<
")");
434 if (m_multiSlider && m_positionMapper)
436 m_positionMapper->setOutputIncludePositions(m_multiSlider->getOutputsInLayer(TwoDFieldMultisliderComponent::ChannelLayer(layerVal)));
437 m_positionMapper->setOutputIgnorePositions(m_multiSlider->getDirectiveOutputsNotInLayer(TwoDFieldMultisliderComponent::ChannelLayer(layerVal)));
438 m_positionMapper->mapInputPosition(channel, { -xVal, yVal }, sharpnessVal);
440 if (juce::NotificationType::dontSendNotification != notification)
442 if (xValOpt.has_value() || yValOpt.has_value())
444 if (layerOpt.has_value())
445 m_multiSlider->setInputPositionLayer(channel, TwoDFieldMultisliderComponent::ChannelLayer(layerVal), juce::dontSendNotification);
446 if (sharpnessOpt.has_value())
447 m_multiSlider->setInputPositionSharpness(channel, sharpnessVal, juce::dontSendNotification);
451 if (m_admOsController)
454 if (xValOpt.has_value() || yValOpt.has_value())
456 if (xValOpt.has_value())
458 if (yValOpt.has_value())
460 if (xValOpt.has_value() || yValOpt.has_value() || layerOpt.has_value())
462 if (sharpnessOpt.has_value())
469 std::map<std::uint16_t, std::map<std::uint16_t, bool>> crosspointStates;
470 std::map<std::uint16_t, std::map<std::uint16_t, float>> crosspointValues;
471 for (
auto const& cToOdKV : channelToOutputsDists)
473 crosspointStates[channel][std::uint16_t(m_multiSlider->getChannelNumberForChannelTypeInCurrentConfiguration(cToOdKV.first))] =
true;
474 crosspointValues[channel][std::uint16_t(m_multiSlider->getChannelNumberForChannelTypeInCurrentConfiguration(cToOdKV.first))] = cToOdKV.second;