update free filter node selection and deletion to better support ios. add enable toggles for free filter and ratio in tabs. on ios shutdown audio when going to background and not doing anything. some layout fixes

This commit is contained in:
essej 2022-04-18 15:11:22 -04:00
parent c37aab3dcc
commit 2e3a74e137
11 changed files with 209 additions and 52 deletions

View File

@ -241,7 +241,11 @@ Rectangle<int> CustomLookAndFeel::getTabButtonExtraComponentBounds (const TabBar
void CustomLookAndFeel::createTabTextLayout (const TabBarButton& button, float length, float depth,
Colour colour, TextLayout& textLayout)
{
float fontsize = button.getExtraComponent() != nullptr ? jmin(depth, 32.0f) * 0.85f : jmin(depth, 32.0f) * 0.5f;
float hscale = 0.6f;
#if JUCE_IOS
hscale = 0.5f;
#endif
float fontsize = button.getExtraComponent() != nullptr ? jmin(depth, 32.0f) * hscale : jmin(depth, 32.0f) * hscale;
Font font = myFont.withHeight(fontsize * fontScale);
font.setUnderline (button.hasKeyboardFocus (false));

View File

@ -138,8 +138,10 @@ public:
void shutdown() override
{
DBG("shutdown");
if (mainWindow.get() != nullptr)
if (mainWindow.get() != nullptr) {
mainWindow->pluginHolder->savePluginState();
mainWindow->pluginHolder->saveAudioDeviceState();
}
mainWindow = nullptr;
appProperties.saveIfNeeded();
@ -148,8 +150,20 @@ public:
void suspended() override
{
DBG("suspended");
if (mainWindow.get() != nullptr)
if (mainWindow.get() != nullptr) {
mainWindow->pluginHolder->savePluginState();
mainWindow->pluginHolder->saveAudioDeviceState();
if (auto * sonoproc = dynamic_cast<PaulstretchpluginAudioProcessor*>(mainWindow->pluginHolder->processor.get())) {
if (sonoproc->getBoolParameter(cpi_pause_enabled)->get() && !sonoproc->isRecordingEnabled()
&& !mainWindow->pluginHolder->isInterAppAudioConnected()) {
// shutdown audio engine
DBG("not active, shutting down audio");
mainWindow->getDeviceManager().closeAudioDevice();
sonoproc->setPlayHead (nullptr);
}
}
}
appProperties.saveIfNeeded();
@ -158,15 +172,27 @@ public:
void resumed() override
{
Desktop::getInstance().setScreenSaverEnabled(false);
Desktop::getInstance().setScreenSaverEnabled(false);
if (auto * dev = mainWindow->getDeviceManager().getCurrentAudioDevice()) {
if (!dev->isPlaying()) {
DBG("dev not playing, restarting");
mainWindow->getDeviceManager().restartLastAudioDevice();
}
}
else {
DBG("was not actve: restarting");
mainWindow->getDeviceManager().restartLastAudioDevice();
}
}
//==============================================================================
void systemRequestedQuit() override
{
DBG("Requested quit");
if (mainWindow.get() != nullptr)
if (mainWindow.get() != nullptr) {
mainWindow->pluginHolder->savePluginState();
mainWindow->pluginHolder->saveAudioDeviceState();
}
appProperties.saveIfNeeded();

View File

@ -239,7 +239,7 @@ public:
#if JucePlugin_Enable_IAA && JUCE_IOS
if (auto device = dynamic_cast<iOSAudioIODevice*> (deviceManager.getCurrentAudioDevice()))
{
processor->setPlayHead (device->getAudioPlayHead());
processor->setPlayHead (device->getAudioPlayHead());
device->setMidiMessageCollector (&player.getMidiMessageCollector());
}
#endif

View File

@ -54,7 +54,8 @@ enum SettingsMenuIds
SettingsSaveCaptureDiskId = 9,
SettingsMuteProcessedCaptureId = 10,
SettingsAudioSettingsId = 11,
SettingsSliderSnapId = 12
SettingsSliderSnapId = 12,
SettingsRestorePlayStateId = 13
};
@ -326,6 +327,12 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
auto filtgroup = std::make_unique<ParameterGroupComponent>("", FilterGroup, &processor);
filtgroup->addParameterComponent(m_parcomps[cpi_filter_low].get());
filtgroup->addParameterComponent(m_parcomps[cpi_filter_high].get());
if (auto * slid = m_parcomps[cpi_filter_low]->getSlider()) {
slid->setNumDecimalPlacesToDisplay(0);
}
if (auto * slid = m_parcomps[cpi_filter_high]->getSlider()) {
slid->setNumDecimalPlacesToDisplay(0);
}
filtgroup->EnabledChangedCallback = [this]() {
processor.setDirty();
};
@ -470,7 +477,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
//m_wavefilter_tab.addTab("Spectrum", Colours::white, &m_sonogram, false);
#if 0
#if 1
// TODO
auto * ratiotoggle = new DrawableButton("rt", DrawableButton::ImageFitted);
std::unique_ptr<Drawable> powerimg(Drawable::createFromImageData(BinaryData::power_svg, BinaryData::power_svgSize));
@ -479,6 +486,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
ratiotoggle->setClickingTogglesState(true);
ratiotoggle->setColour(DrawableButton::backgroundColourId, Colours::transparentBlack);
ratiotoggle->setColour(DrawableButton::backgroundOnColourId, Colours::transparentBlack);
ratiotoggle->setSize(32,32);
ratiotoggle->onClick = [this]() {
setSpectrumProcGroupEnabled(RatiosGroup, !isSpectrumProcGroupEnabled(RatiosGroup));
};
@ -488,6 +496,7 @@ PaulstretchpluginAudioProcessorEditor::PaulstretchpluginAudioProcessorEditor(Pau
fftoggle->setClickingTogglesState(true);
fftoggle->setColour(DrawableButton::backgroundColourId, Colours::transparentBlack);
fftoggle->setColour(DrawableButton::backgroundOnColourId, Colours::transparentBlack);
fftoggle->setSize(32,32);
fftoggle->onClick = [this]() {
setSpectrumProcGroupEnabled(FreeFilterGroup, !isSpectrumProcGroupEnabled(FreeFilterGroup));
};
@ -619,6 +628,10 @@ void PaulstretchpluginAudioProcessorEditor::executeModalMenuAction(int menuid, i
else if (r == SettingsSliderSnapId)
{
toggleBool(processor.m_use_jumpsliders);
}
else if (r == SettingsRestorePlayStateId)
{
toggleBool(processor.m_restore_playstate);
}
else if (r == SettingsAboutId)
{
@ -793,18 +806,19 @@ void PaulstretchpluginAudioProcessorEditor::resized()
FlexBox scompbox;
if (w >= 700) {
int halfgroupw = groupw/2 - 2*groupmargin;
shiftbox.flexDirection = FlexBox::Direction::row;
minh = m_pargroups[FrequencyShiftGroup]->getMinimumHeight(minw);
minh = m_pargroups[FrequencyShiftGroup]->getMinimumHeight(halfgroupw);
shiftbox.items.add(FlexItem(minw, minh, *m_pargroups[FrequencyShiftGroup]).withFlex(1));
shiftbox.items.add(FlexItem(4, minh));
shiftbox.items.add(FlexItem(groupmargin*2, minh));
shiftbox.items.add(FlexItem(minw, minh, *m_pargroups[PitchShiftGroup]).withFlex(1));
groupsbox.items.add(FlexItem(minw, minh, shiftbox).withMargin(groupmargin));
gheight += minh + 2*groupmargin;
scompbox.flexDirection = FlexBox::Direction::row;
minh = m_pargroups[FrequencySpreadGroup]->getMinimumHeight(minw);
minh = m_pargroups[FrequencySpreadGroup]->getMinimumHeight(halfgroupw);
scompbox.items.add(FlexItem(minw, minh, *m_pargroups[FrequencySpreadGroup]).withFlex(1));
scompbox.items.add(FlexItem(4, minh));
scompbox.items.add(FlexItem(groupmargin*2, minh));
scompbox.items.add(FlexItem(minw, minh, *m_pargroups[CompressGroup]).withFlex(1));
groupsbox.items.add(FlexItem(minw, minh, scompbox).withMargin(groupmargin));
gheight += minh + 2*groupmargin;
@ -918,8 +932,11 @@ void PaulstretchpluginAudioProcessorEditor::resized()
if (m_wavefilter_tab.getNumTabs() > 3) {
// bring it back
int currtab = m_wavefilter_tab.getCurrentTabIndex();
m_wavefilter_tab.removeTab(3);
m_wavefilter_tab.setCurrentTabIndex(0);
if (currtab == 3) {
m_wavefilter_tab.setCurrentTabIndex(0);
}
addAndMakeVisible(m_groupviewport.get());
}
m_shortMode = false;
@ -931,8 +948,11 @@ void PaulstretchpluginAudioProcessorEditor::resized()
if (m_wavefilter_tab.getNumTabs() > 3) {
// bring it back
int currtab = m_wavefilter_tab.getCurrentTabIndex();
m_wavefilter_tab.removeTab(3);
m_wavefilter_tab.setCurrentTabIndex(0);
if (currtab == 3) {
m_wavefilter_tab.setCurrentTabIndex(0);
}
addAndMakeVisible(m_groupviewport.get());
}
@ -946,6 +966,7 @@ void PaulstretchpluginAudioProcessorEditor::resized()
//mainbox.items.add(FlexItem(minw, toggleh, togglesbox).withMargin(margin).withFlex(0));
mainbox.items.add(FlexItem(minw, volh, volbox).withMargin(margin).withFlex(0));
mainbox.items.add(FlexItem(6, 3));
mainbox.items.add(FlexItem(minw, stretchH, *m_stretchgroup).withMargin(margin).withFlex(0));
}
@ -1089,6 +1110,13 @@ void PaulstretchpluginAudioProcessorEditor::timerCallback(int id)
m_stretchgroup->replaceParameterComponent(m_parcomps[cpi_dryplayrate].get(), m_parcomps[cpi_stretchamount].get());
}
if (auto * toggle = dynamic_cast<Button*>(m_wavefilter_tab.getTabbedButtonBar().getTabButton(1)->getExtraComponent())) {
toggle->setToggleState(isSpectrumProcGroupEnabled(RatiosGroup), dontSendNotification);
}
if (auto * toggle = dynamic_cast<Button*>(m_wavefilter_tab.getTabbedButtonBar().getTabButton(2)->getExtraComponent())) {
toggle->setToggleState(isSpectrumProcGroupEnabled(FreeFilterGroup), dontSendNotification);
}
updateAllSliders();
//m_parcomps[cpi_dryplayrate]->setVisible(*processor.getBoolParameter(cpi_bypass_stretch));
@ -1156,6 +1184,7 @@ void PaulstretchpluginAudioProcessorEditor::showSettingsMenu()
m_settings_menu.addItem(SettingsLoadFileWithStateId, "Load file with plugin state", true, processor.m_load_file_with_state);
m_settings_menu.addItem(SettingsPlayHostTransId, "Play when host transport running", true, processor.m_play_when_host_plays);
m_settings_menu.addItem(SettingsCaptureHostTransId, "Capture when host transport running", true, processor.m_capture_when_host_plays);
m_settings_menu.addItem(SettingsRestorePlayStateId, "Restore playing state", true, processor.m_restore_playstate);
m_settings_menu.addSeparator();
m_settings_menu.addItem(SettingsMutePassthruCaptureId, "Mute passthrough while capturing", true, processor.m_mute_while_capturing);
m_settings_menu.addItem(SettingsMuteProcessedCaptureId, "Mute processed audio output while capturing", true, processor.m_mute_processed_while_capturing);
@ -1626,8 +1655,6 @@ void WaveformComponent::mouseDoubleClick(const MouseEvent & e)
void WaveformComponent::mouseWheelMove(const MouseEvent & e, const MouseWheelDetails & wd)
{
//return;
double width = getWidth();
double normt = viewXToNormalized(e.x);
double curlen = m_view_range.getLength();
@ -1658,6 +1685,39 @@ void WaveformComponent::mouseWheelMove(const MouseEvent & e, const MouseWheelDet
}
void WaveformComponent::mouseMagnify (const MouseEvent& e, float scaleFactor)
{
#if 0
double width = getWidth();
double normt = viewXToNormalized(e.x);
double curlen = m_view_range.getLength();
double zoomFactor = 1.0 - curlen;
double newfact = jlimit(0.0, 1.0, zoomFactor + scaleFactor);
double xratio = e.x / width;
auto newScale = jmax (0.001, 1.0 * (1.0 - jlimit (0.0, 0.99, newfact)));
double t0 = normt - newScale * xratio;
double t1 = normt + newScale * (1.0 - xratio);
t0 = jlimit(0.0,1.0, t0);
t1 = jlimit(0.0,1.0, t1);
DBG("MAG normt: " << normt << " posratio: " << xratio << " curlen: " << curlen << " t0: " << t0 << " t1: " << t1 << " mscale: " << scaleFactor);
jassert(t1 > t0);
m_view_range = { t0,t1 };
//m_view_range = m_view_range.constrainRange({ 0.0, 1.0 });
jassert(m_view_range.getStart() >= 0.0 && m_view_range.getEnd() <= 1.0);
jassert(m_view_range.getLength() > 0.001);
if (ViewRangeChangedCallback)
ViewRangeChangedCallback(m_view_range);
m_image_dirty = true;
repaint();
#endif
}
void WaveformComponent::setAudioInfo(double sr, double seekpos, int fftsize)
{
m_sr = sr;
@ -1991,8 +2051,8 @@ ParameterComponent::ParameterComponent(AudioProcessorParameter * par, bool notif
m_slider->setTextBoxStyle(Slider::TextBoxLeft, false, 60, 34);
m_slider->addListener(this);
m_slider->setViewportIgnoreDragFlag(true);
m_slider->setScrollWheelEnabled(false
);
m_slider->setDoubleClickReturnValue(true, intpar->convertFrom0to1(par->getDefaultValue()));
m_slider->setScrollWheelEnabled(false);
m_slider->setTitle(intpar->getName(50));
}
AudioParameterChoice* choicepar = dynamic_cast<AudioParameterChoice*>(par);
@ -2032,13 +2092,20 @@ void ParameterComponent::resized()
int h = getHeight();
if (m_slider)
{
int smallWidthThresh = 280;
int medWidthThresh = 350;
#if JUCE_IOS
smallWidthThresh = 360;
medWidthThresh = 420;
#endif
//int labw = 200;
int labw = 120;
if (getWidth() < 280) {
if (getWidth() < smallWidthThresh) {
labw = 60;
m_label.setFont(12.0f);
}
else if (getWidth() < 350) {
else if (getWidth() < medWidthThresh) {
labw = 100;
m_label.setFont(14.0f);
} else {
@ -2371,9 +2438,14 @@ RatioMixerEditor::RatioMixerEditor(int numratios)
ratlevslid->setRange(0.0, 1.0);
ratlevslid->setNumDecimalPlacesToDisplay(3);
ratlevslid->setSliderStyle(Slider::LinearVertical);
if (i==3)
ratlevslid->setValue(1.0,dontSendNotification);
else ratlevslid->setValue(0.0,dontSendNotification);
if (i==2) {
ratlevslid->setValue(1.0,dontSendNotification);
ratlevslid->setDoubleClickReturnValue(true, 1.0);
}
else {
ratlevslid->setValue(0.0,dontSendNotification);
ratlevslid->setDoubleClickReturnValue(true, 0.0);
}
ratlevslid->onValueChange = [this, i]() { OnRatioLevelChanged(i, m_ratio_level_sliders[i]->getValue()); };
addAndMakeVisible(ratlevslid.get());
m_ratio_level_sliders.emplace_back(std::move(ratlevslid));

View File

@ -204,6 +204,7 @@ public:
void mouseMove(const MouseEvent& e) override;
void mouseDoubleClick(const MouseEvent& e) override;
void mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& wd) override;
void mouseMagnify (const MouseEvent& event, float scaleFactor) override;
void setAudioInfo(double sr, double seekpos, int fftsize);
Range<double> getTimeSelection();
void setTimeSelection(Range<double> rng);

View File

@ -159,7 +159,7 @@ m_bufferingthread("pspluginprebufferthread"), m_is_stand_alone_offline(is_stand_
addParameter(new AudioParameterBool("capture_enabled0", "Capture", false)); // 26
m_outchansparam = new AudioParameterInt("numoutchans0", "Num outs", 2, 8, 2); // 27
addParameter(m_outchansparam); // 27
addParameter(new AudioParameterBool("pause_enabled0", "Pause", false)); // 28
addParameter(new AudioParameterBool("pause_enabled0", "Pause", true)); // 28
addParameter(new AudioParameterFloat("maxcapturelen_0", "Max capture length", 1.0f, 120.0f, 10.0f)); // 29
addParameter(new AudioParameterBool("passthrough0", "Pass input through", false)); // 30
addParameter(new AudioParameterBool("markdirty0", "Internal (don't use)", false)); // 31
@ -317,6 +317,7 @@ ValueTree PaulstretchpluginAudioProcessor::getStateTree(bool ignoreoptions, bool
storeToTreeProperties(paramtree, nullptr, "pluginwidth", mPluginWindowWidth);
storeToTreeProperties(paramtree, nullptr, "pluginheight", mPluginWindowHeight);
storeToTreeProperties(paramtree, nullptr, "jumpsliders", m_use_jumpsliders);
storeToTreeProperties(paramtree, nullptr, "restoreplaystate", m_restore_playstate);
return paramtree;
}
@ -325,6 +326,8 @@ void PaulstretchpluginAudioProcessor::setStateFromTree(ValueTree tree)
{
if (tree.isValid())
{
bool origpaused = getBoolParameter(cpi_pause_enabled)->get();
{
ScopedLock locker(m_cs);
ValueTree freefilterstate = tree.getChildWithName("freefilter_envelope");
@ -337,6 +340,7 @@ void PaulstretchpluginAudioProcessor::setStateFromTree(ValueTree tree)
getFromTreeProperties(tree, "pluginwidth", mPluginWindowWidth);
getFromTreeProperties(tree, "pluginheight", mPluginWindowHeight);
getFromTreeProperties(tree, "jumpsliders", m_use_jumpsliders);
getFromTreeProperties(tree, "restoreplaystate", m_restore_playstate);
if (tree.hasProperty("numspectralstagesb"))
{
@ -362,6 +366,12 @@ void PaulstretchpluginAudioProcessor::setStateFromTree(ValueTree tree)
m_use_backgroundbuffering = false;
else
setPreBufferAmount(m_is_stand_alone_offline ? 0 : prebufamt);
if (!m_restore_playstate) {
// use previous paused value
*(getBoolParameter(cpi_pause_enabled)) = origpaused;
}
if (m_load_file_with_state == true)
{
String fn = tree.getProperty("importedfile");

View File

@ -216,7 +216,9 @@ public:
bool m_mute_while_capturing = false;
bool m_mute_processed_while_capturing = false;
bool m_use_backgroundbuffering = true;
void resetParameters();
bool m_restore_playstate = true;
void resetParameters();
void setPreBufferAmount(int x);
int getPreBufferAmount();
bool m_load_file_with_state = true;

View File

@ -60,17 +60,17 @@ void EnvelopeComponent::show_bubble(int x, int y, const envelope_point& node)
void EnvelopeComponent::resized()
{
//#if JUCE_IOS
#if JUCE_IOS
int butw = 38;
int buth = 38;
m_menubutton.setBounds(getWidth() - butw - 1, 1, butw, buth);
//#endif
int buth = 34;
m_menubutton.setBounds((getWidth() - butw)/2, 1, butw, buth);
#endif
}
void EnvelopeComponent::paint(Graphics& g)
{
float targsize = 8.0;
float targsize = 10.0;
#if JUCE_IOS
targsize = 16.0;
#endif
@ -208,8 +208,8 @@ void EnvelopeComponent::mouseDrag(const MouseEvent& ev)
{
right_bound = m_envelope->GetNodeAtIndex(m_node_to_drag + 1).pt_x;
}
double normx = jmap((double)ev.x, 0.0, (double)getWidth(), m_view_start_time, m_view_end_time);
double normy = jmap((double)getHeight() - ev.y, 0.0, (double)getHeight(), m_view_start_value, m_view_end_value);
double normx = jmap((double)ev.x - m_touch_offset.x, 0.0, (double)getWidth(), m_view_start_time, m_view_end_time);
double normy = jmap((double)getHeight() - (ev.y - m_touch_offset.y ), 0.0, (double)getHeight(), m_view_start_value, m_view_end_value);
pt.pt_x=jlimit(left_bound+0.001, right_bound - 0.001, normx);
pt.pt_y=jlimit(0.0,1.0,normy);
m_envelope->updateMinMaxValues();
@ -230,8 +230,10 @@ void EnvelopeComponent::mouseMove(const MouseEvent & ev)
{
if (m_mouse_down == false)
{
#if !JUCE_IOS
show_bubble(ev.x, ev.y, m_envelope->GetNodeAtIndex(m_node_to_drag));
setMouseCursor(MouseCursor::PointingHandCursor);
#endif
}
}
else
@ -250,6 +252,7 @@ void EnvelopeComponent::showPopupMenu()
PopupMenu menu;
PopupMenu::Options opts;
menu.addItem(1, "Reset");
menu.addItem(5, "Delete selected");
menu.addItem(2, "Invert");
menu.addItem(3, "Wrap envelope X transform", true, m_envelope->m_transform_wrap_x);
menu.addItem(4, "Envelope Y random linear interpolation", true, m_envelope->m_transform_y_random_linear_interpolation);
@ -262,7 +265,7 @@ void EnvelopeComponent::showPopupMenu()
ScopedLock locker(*m_cs);
m_envelope->ResetEnvelope();
}
if (r == 2)
else if (r == 2)
{
for (int i = 0; i < m_envelope->GetNumPoints(); ++i)
{
@ -270,14 +273,18 @@ void EnvelopeComponent::showPopupMenu()
m_envelope->GetNodeAtIndex(i).pt_y = val;
}
}
if (r == 3)
else if (r == 3)
{
toggleBool(m_envelope->m_transform_wrap_x);
}
if (r == 4)
else if (r == 4)
{
toggleBool(m_envelope->m_transform_y_random_linear_interpolation);
}
else if (r == 5)
{
deleteSelectedNodes();
}
repaint();
};
@ -299,6 +306,7 @@ void EnvelopeComponent::mouseDown(const MouseEvent & ev)
return;
}
m_node_to_drag = find_hot_envelope_point(ev.x, ev.y);
m_touch_offset = {0, 0};
m_mouse_down = true;
m_segment_drag_info = { findHotEnvelopeSegment(ev.x, ev.y, true),false };
if (m_segment_drag_info.first >= 0)
@ -322,9 +330,18 @@ void EnvelopeComponent::mouseDown(const MouseEvent & ev)
repaint();
return;
}
if (m_node_to_drag >= 0 && ev.mods.isShiftDown()==true)
if (m_node_to_drag >= 0)
{
int oldstatus = m_envelope->GetNodeAtIndex(m_node_to_drag).Status;
const envelope_point& pt = m_envelope->GetNodeAtIndex(m_node_to_drag);
double xcor = jmap(pt.pt_x, m_view_start_time, m_view_end_time, 0.0, (double)getWidth());
double ycor = (double)getHeight() - jmap(pt.pt_y, m_view_start_value, m_view_end_value, 0.0, (double)getHeight());
m_touch_offset = { ev.x - (int)xcor , ev.y - (int)ycor };
if (!ev.mods.isShiftDown()) {
m_envelope->SetNodeStatusForAll(0);
}
int oldstatus = m_envelope->GetNodeAtIndex(m_node_to_drag).Status;
if (oldstatus==0)
m_envelope->GetNodeAtIndex(m_node_to_drag).Status=1;
else m_envelope->GetNodeAtIndex(m_node_to_drag).Status=0;
@ -342,6 +359,10 @@ void EnvelopeComponent::mouseDown(const MouseEvent & ev)
m_envelope->updateMinMaxValues();
m_node_to_drag = find_hot_envelope_point(ev.x, ev.y);
// deselect all
m_envelope->SetNodeStatusForAll(0);
m_envelope->GetNodeAtIndex(m_node_to_drag).Status=1; // select it
//m_mouse_down = false;
OnEnvelopeEdited(m_envelope.get());
repaint();
@ -350,8 +371,12 @@ void EnvelopeComponent::mouseDown(const MouseEvent & ev)
void EnvelopeComponent::mouseUp(const MouseEvent &ev)
{
if (ev.mods == ModifierKeys::noModifiers)
m_bubble.setVisible(false);
#if JUCE_IOS
m_bubble.setVisible(false);
#endif
if (ev.mods == ModifierKeys::noModifiers) {
m_bubble.setVisible(false);
}
if (m_node_that_was_dragged >= 0 || m_segment_drag_info.second==true)
{
OnEnvelopeEdited(m_envelope.get());
@ -366,6 +391,19 @@ void EnvelopeComponent::mouseUp(const MouseEvent &ev)
}
}
void EnvelopeComponent::deleteSelectedNodes()
{
m_node_to_drag = -1;
{
ScopedLock locker(*m_cs);
m_envelope->removePointsConditionally([](const envelope_point& pt) { return pt.Status == 1; });
if (m_envelope->GetNumPoints() == 0)
m_envelope->AddNode({ 0.0,0.5 });
}
OnEnvelopeEdited(m_envelope.get());
}
bool EnvelopeComponent::keyPressed(const KeyPress & ev)
{
if (m_envelope == nullptr)
@ -418,15 +456,8 @@ bool EnvelopeComponent::keyPressed(const KeyPress & ev)
if (ev == KeyPress::deleteKey)
{
m_node_to_drag = -1;
{
ScopedLock locker(*m_cs);
m_envelope->removePointsConditionally([](const envelope_point& pt) { return pt.Status == 1; });
if (m_envelope->GetNumPoints() == 0)
m_envelope->AddNode({ 0.0,0.5 });
}
repaint();
OnEnvelopeEdited(m_envelope.get());
deleteSelectedNodes();
repaint();
return true;
}
return false;
@ -441,7 +472,7 @@ int EnvelopeComponent::find_hot_envelope_point(double xcor, double ycor)
const envelope_point& pt = m_envelope->GetNodeAtIndex(i);
double ptxcor = jmap(pt.pt_x, m_view_start_time, m_view_end_time, 0.0, (double)getWidth());
double ptycor = (double)getHeight() - jmap(pt.pt_y, m_view_start_value, m_view_end_value, 0.0, (double)getHeight());
float targsize = 8.0;
float targsize = 10.0;
#if JUCE_IOS
targsize = 20;
#endif
@ -456,7 +487,7 @@ int EnvelopeComponent::find_hot_envelope_point(double xcor, double ycor)
int EnvelopeComponent::findHotEnvelopeSegment(double xcor, double ycor, bool detectsegment)
{
float targsize = 8.0;
float targsize = 10.0;
#if JUCE_IOS
targsize = 20.0;
#endif
@ -470,7 +501,7 @@ int EnvelopeComponent::findHotEnvelopeSegment(double xcor, double ycor, bool det
float xcor0 = (float)jmap<double>(pt0.pt_x, m_view_start_time, m_view_end_time, 0.0, getWidth());
float xcor1 = (float)jmap<double>(pt1.pt_x, m_view_start_time, m_view_end_time, 0.0, getWidth());
float segwidth = xcor1 - xcor0;
juce::Rectangle<float> segrect(xcor0+8.0f, 0.0f, segwidth-16.0f, (float)getHeight());
juce::Rectangle<float> segrect(xcor0+targsize, 0.0f, segwidth-2*targsize, (float)getHeight());
if (segrect.contains((float)xcor, (float)ycor))
{
if (detectsegment == false)

View File

@ -56,6 +56,8 @@ public:
private:
void showPopupMenu();
void deleteSelectedNodes();
std::shared_ptr<breakpoint_envelope> m_envelope;
String m_name;
Colour m_env_color{ Colours::yellow };
@ -67,8 +69,10 @@ private:
int findHotEnvelopeSegment(double xcor, double ycor, bool detectsegment);
bool m_mouse_down = false;
int m_node_to_drag = -1;
Point<int> m_touch_offset;
std::pair<int, bool> m_segment_drag_info{ -1,false };
int m_node_that_was_dragged = -1;
int m_selected_node = -1;
String m_last_tip;
BubbleMessageComponent m_bubble;
TextButton m_menubutton;

View File

@ -390,6 +390,13 @@ public:
if (indx>(int)m_nodes.size()-1) i=(int)m_nodes.size()-1;
m_nodes[i].Status=nstatus;
}
void SetNodeStatusForAll(int nstatus)
{
for (int i=0; i < m_nodes.size(); ++i) {
m_nodes[i].Status = nstatus;
}
}
void SetNode(int indx, envelope_point anode)
{
int i=indx;

View File

@ -88,7 +88,7 @@
</MAINGROUP>
<EXPORTFORMATS>
<XCODE_IPHONE targetFolder="Builds/iOS" iosDevelopmentTeamID="XCS435894D" microphonePermissionNeeded="1"
iosBackgroundAudio="1" buildNumber="105" iosScreenOrientation="UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown"
iosBackgroundAudio="1" buildNumber="106" iosScreenOrientation="UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown"
iPadScreenOrientation="UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortrait,UIInterfaceOrientationPortraitUpsideDown"
UIStatusBarHidden="0" UIRequiresFullScreen="0" customPList="&lt;plist version=&quot;1.0&quot;&gt;&#10;&lt;dict&gt;&#10;&#10;&#10;&lt;key&gt;ITSAppUsesNonExemptEncryption&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#10;&lt;key&gt;UIStatusBarHidden&lt;/key&gt;&#10;&#9;&lt;false/&gt;&#10;&#9;&lt;key&gt;UIStatusBarStyle&lt;/key&gt;&#10;&#9;&lt;string&gt;UIStatusBarStyleLightContent&lt;/string&gt;&#10;&#10;&lt;key&gt;UIViewControllerBasedStatusBarAppearance&lt;/key&gt;&#10;&lt;false/&gt;&#10;&#10;&#10;&lt;key&gt;NSLocalNetworkUsageDescription&lt;/key&gt;&#10;&#9;&lt;string&gt;DrumJamPad uses networking to communicate with other local services&lt;/string&gt;&#10;&#10;&lt;key&gt;CFBundleDocumentTypes&lt;/key&gt;&#10;&#9;&lt;array&gt;&#10;&#9;&#9;&lt;dict&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeIconFiles&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;array/&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeName&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Audio File&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;CFBundleTypeRole&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Viewer&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;LSHandlerRank&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;string&gt;Owner&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;key&gt;LSItemContentTypes&lt;/key&gt;&#10;&#9;&#9;&#9;&lt;array&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;com.microsoft.waveform-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.aiff-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;com.apple.coreaudio-format&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.mpeg-4-audio&lt;/string&gt;&#10;&#9;&#9;&#9;&#9;&lt;string&gt;public.mp3&lt;/string&gt;&#10;&#9;&#9;&#9;&lt;/array&gt;&#10;&#9;&#9;&lt;/dict&gt;&#10;&#9;&#9;&lt;/array&gt;&#10;&#10;&lt;/dict&gt;&#10;&lt;/plist&gt;"
UIFileSharingEnabled="1" UISupportsDocumentBrowser="1" extraDefs="PS_USE_VDSP_FFT=1"