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);
200 DBG(juce::String(__FUNCTION__) <<
" handle n" << objNum <<
" t" << admObjType);
202 jassert(m_admOsController);
203 if (!m_admOsController)
205 jassert(m_multiSlider);
221 changeInputPosition(std::uint16_t(objNum), xVal, std::nullopt, std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
234 changeInputPosition(std::uint16_t(objNum), std::nullopt, yVal, std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
246 changeInputPosition(std::uint16_t(objNum), std::nullopt, std::nullopt, std::nullopt, (zVal > 0.5f ? TwoDFieldMultisliderComponent::ChannelLayer::PositionedHeight : TwoDFieldMultisliderComponent::ChannelLayer::Positioned), juce::NotificationType::sendNotification);
260 changeInputPosition(std::uint16_t(objNum), std::get<0>(xyVals), std::get<1>(xyVals), std::nullopt, std::nullopt, juce::NotificationType::sendNotification);
273 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);
281 changeInputPosition(std::uint16_t(objNum), std::nullopt, std::nullopt, 1.0f - widthVal, std::nullopt, juce::NotificationType::sendNotification);
302 if (ioCount.first != m_inputSelectButtons.size() || ioCount.first != m_inputMuteButtons.size() || force)
304 auto templateColums = juce::Array<juce::Grid::TrackInfo>();
305 for (
auto in = 0; in < ioCount.first; in++)
306 templateColums.add(juce::Grid::TrackInfo(juce::Grid::Px(
m_controlsSize)));
308 m_inputMuteButtons.resize(ioCount.first);
309 m_inputSelectButtons.resize(ioCount.first);
310 m_inputControlsGrid->items.clear();
311 m_inputControlsGrid->templateRows = { juce::Grid::TrackInfo(juce::Grid::Fr(1)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) };
312 m_inputControlsGrid->templateColumns = templateColums;
314 for (
auto i = 0; i < ioCount.first; i++)
316 auto in = std::uint16_t(i + 1);
317 m_inputSelectButtons.at(i) = std::make_unique<juce::TextButton>(
"In " + juce::String(in));
318 m_inputSelectButtons.at(i)->setClickingTogglesState(
true);
319 m_inputSelectButtons.at(i)->setColour(juce::TextButton::ColourIds::buttonOnColourId, getLookAndFeel().findColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId));
320 m_inputSelectButtons.at(i)->onClick = [
this, i] {
321 if (m_inputSelectButtons.size() > i)
323 auto in = std::uint16_t(i + 1);
324 if (m_inputSelectButtons.at(i)->getToggleState())
332 m_horizontalScrollContainerComponent->addAndMakeVisible(m_inputSelectButtons.at(i).get());
333 m_inputControlsGrid->items.add(juce::GridItem(m_inputSelectButtons.at(i).get()));
335 for (
auto i = 0; i < ioCount.first; i++)
337 auto in = std::uint16_t(i + 1);
338 m_inputMuteButtons.at(i) = std::make_unique<juce::TextButton>(
"M");
339 m_inputMuteButtons.at(i)->setClickingTogglesState(
true);
341 m_inputMuteButtons.at(i)->setColour(juce::TextButton::ColourIds::buttonOnColourId, juce::Colours::red);
342 m_inputMuteButtons.at(i)->onClick = [
this, i] {
343 auto inputMuteStates = std::map<std::uint16_t, bool>();
344 auto in = std::uint16_t(i + 1);
345 inputMuteStates[in] = m_inputMuteButtons.at(i)->getToggleState();
349 if (m_admOsController)
352 m_horizontalScrollContainerComponent->addAndMakeVisible(m_inputMuteButtons.at(i).get());
353 m_inputControlsGrid->items.add(juce::GridItem(m_inputMuteButtons.at(i).get()));
390 auto oldChannel = m_currentInputChannel;
391 m_currentInputChannel = channel;
392 if (oldChannel != channel)
396 for (
auto i = 0; i < ioCount.first; i++)
398 auto in = std::uint16_t(i + 1);
399 auto state = channel == in;
400 if (
nullptr != m_inputSelectButtons.at(i))
401 m_inputSelectButtons.at(i)->setToggleState(state, juce::dontSendNotification);
402 if (
nullptr != m_multiSlider)
403 m_multiSlider->selectInput(in, state);
407void 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)
410 if (xValOpt.has_value())
411 xVal = xValOpt.value();
412 else if (m_admOsController)
416 if (yValOpt.has_value())
417 yVal = yValOpt.value();
418 else if (m_admOsController)
421 float sharpnessVal = 0.0f;
422 if (sharpnessOpt.has_value())
423 sharpnessVal = sharpnessOpt.value();
424 else if (m_admOsController)
428 if (layerOpt.has_value())
429 layerVal = layerOpt.value();
430 else if (m_admOsController)
433 layerVal = zVal > 0.5f ? TwoDFieldMultisliderComponent::ChannelLayer::PositionedHeight : TwoDFieldMultisliderComponent::ChannelLayer::Positioned;
436 DBG(juce::String(__FUNCTION__) <<
" new pos: " <<
int(channel) <<
" " << xVal <<
"," << yVal <<
"(" << sharpnessVal <<
" / " << layerVal <<
")");
438 if (m_multiSlider && m_positionMapper)
440 m_positionMapper->setOutputIncludePositions(m_multiSlider->getOutputsInLayer(TwoDFieldMultisliderComponent::ChannelLayer(layerVal)));
441 m_positionMapper->setOutputIgnorePositions(m_multiSlider->getDirectiveOutputsNotInLayer(TwoDFieldMultisliderComponent::ChannelLayer(layerVal)));
442 m_positionMapper->mapInputPosition(channel, { -xVal, yVal }, sharpnessVal);
444 if (juce::NotificationType::dontSendNotification != notification)
446 if (xValOpt.has_value() || yValOpt.has_value())
448 if (layerOpt.has_value())
449 m_multiSlider->setInputPositionLayer(channel, TwoDFieldMultisliderComponent::ChannelLayer(layerVal), juce::dontSendNotification);
450 if (sharpnessOpt.has_value())
451 m_multiSlider->setInputPositionSharpness(channel, sharpnessVal, juce::dontSendNotification);
455 if (m_admOsController)
458 if (xValOpt.has_value() || yValOpt.has_value())
460 if (xValOpt.has_value())
462 if (yValOpt.has_value())
464 if (xValOpt.has_value() || yValOpt.has_value() || layerOpt.has_value())
466 if (sharpnessOpt.has_value())
473 std::map<std::uint16_t, std::map<std::uint16_t, bool>> crosspointStates;
474 std::map<std::uint16_t, std::map<std::uint16_t, float>> crosspointValues;
475 for (
auto const& cToOdKV : channelToOutputsDists)
477 crosspointStates[channel][std::uint16_t(m_multiSlider->getChannelNumberForChannelTypeInCurrentConfiguration(cToOdKV.first))] =
true;
478 crosspointValues[channel][std::uint16_t(m_multiSlider->getChannelNumberForChannelTypeInCurrentConfiguration(cToOdKV.first))] = cToOdKV.second;