diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index ca0c10b1082..28eaf9a5d9c 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -48,79 +48,79 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) m_otherGroupsTrMap.insert("Master", "Master"); // Mixer Controls - QMenu* mixerMenu = addSubmenu(tr("Mixer")); + QMenu* pMixerMenu = addSubmenu(tr("Mixer")); // Crossfader / Orientation - QMenu* crossfaderMenu = addSubmenu(tr("Crossfader / Orientation"), mixerMenu); + QMenu* pCrossfaderMenu = addSubmenu(tr("Crossfader / Orientation"), pMixerMenu); addControl("[Master]", "crossfader", tr("Crossfader"), tr("Crossfader"), - crossfaderMenu, + pCrossfaderMenu, true); addDeckAndSamplerControl("orientation", tr("Orientation"), tr("Mix orientation (e.g. left, right, center)"), - crossfaderMenu); + pCrossfaderMenu); addDeckAndSamplerControl("orientation_left", tr("Orient Left"), tr("Set mix orientation to left"), - crossfaderMenu); + pCrossfaderMenu); addDeckAndSamplerControl("orientation_center", tr("Orient Center"), tr("Set mix orientation to center"), - crossfaderMenu); + pCrossfaderMenu); addDeckAndSamplerControl("orientation_right", tr("Orient Right"), tr("Set mix orientation to right"), - crossfaderMenu); + pCrossfaderMenu); // Main Output - QMenu* mainOutputMenu = addSubmenu(tr("Main Output"), mixerMenu); + QMenu* pMainOutputMenu = addSubmenu(tr("Main Output"), pMixerMenu); addControl("[Master]", "gain", tr("Main Output Gain"), tr("Main Output gain"), - mainOutputMenu, + pMainOutputMenu, true); addControl("[Master]", "balance", tr("Main Output Balance"), tr("Main Output balance"), - mainOutputMenu, + pMainOutputMenu, true); addControl("[Master]", "delay", tr("Main Output Delay"), tr("Main Output delay"), - mainOutputMenu, + pMainOutputMenu, true); // Headphone - QMenu* headphoneMenu = addSubmenu(tr("Headphone"), mixerMenu); + QMenu* pHeadphoneMenu = addSubmenu(tr("Headphone"), pMixerMenu); addControl("[Master]", "headGain", tr("Headphone Gain"), tr("Headphone gain"), - headphoneMenu, + pHeadphoneMenu, true); addControl("[Master]", "headMix", tr("Headphone Mix"), tr("Headphone mix (pre/main)"), - headphoneMenu, + pHeadphoneMenu, true); addControl("[Master]", "headSplit", tr("Headphone Split Cue"), tr("Toggle headphone split cueing"), - headphoneMenu); + pHeadphoneMenu); addControl("[Master]", "headDelay", tr("Headphone Delay"), tr("Headphone delay"), - headphoneMenu, + pHeadphoneMenu, true); - mixerMenu->addSeparator(); + pMixerMenu->addSeparator(); // EQs - QMenu* eqMenu = addSubmenu(tr("Equalizers"), mixerMenu); + QMenu* pEqMenu = addSubmenu(tr("Equalizers"), pMixerMenu); constexpr int kNumEqRacks = 1; const int iNumDecks = static_cast(ControlObject::get( ConfigKey(kAppGroup, QStringLiteral("num_decks")))); @@ -131,17 +131,17 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) // Since 3-band is by far the most common, stick with that. const int kMaxEqs = 3; for (int deck = 1; deck <= iNumDecks; ++deck) { - QMenu* deckMenu = addSubmenu(QString("Deck %1").arg(deck), eqMenu); + QMenu* pDeckMenu = addSubmenu(QString("Deck %1").arg(deck), pEqMenu); for (int effect = kMaxEqs - 1; effect >= 0; --effect) { const QString group = EqualizerEffectChain::formatEffectSlotGroup( QString("[Channel%1]").arg(deck)); - QMenu* bandMenu = addSubmenu(eqNames[effect], deckMenu); + QMenu* pBandMenu = addSubmenu(eqNames[effect], pDeckMenu); QString control = "parameter%1"; addControl(group, control.arg(effect + 1), tr("Adjust %1").arg(eqNames[effect]), tr("Adjust %1").arg(eqNames[effect]), - bandMenu, + pBandMenu, true, tr("Deck %1").arg(deck)); @@ -150,277 +150,310 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) control.arg(effect + 1), tr("Kill %1").arg(eqNames[effect]), tr("Kill %1").arg(eqNames[effect]), - bandMenu, + pBandMenu, false, tr("Deck %1").arg(deck)); } } } - mixerMenu->addSeparator(); + pMixerMenu->addSeparator(); // Volume / Pfl controls - addDeckAndSamplerControl("volume", tr("Volume"), tr("Volume Fader"), mixerMenu, true); + addDeckAndSamplerControl("volume", tr("Volume"), tr("Volume Fader"), pMixerMenu, true); addDeckAndSamplerControl("volume_set_one", tr("Full Volume"), tr("Set to full volume"), - mixerMenu); + pMixerMenu); addDeckAndSamplerControl("volume_set_zero", tr("Zero Volume"), tr("Set to zero volume"), - mixerMenu); + pMixerMenu); addDeckAndSamplerAndPreviewDeckControl("pregain", tr("Track Gain"), tr("Track Gain knob"), - mixerMenu, + pMixerMenu, true); - addDeckAndSamplerControl("mute", tr("Mute"), tr("Mute button"), mixerMenu); - mixerMenu->addSeparator(); + addDeckAndSamplerControl("mute", tr("Mute"), tr("Mute button"), pMixerMenu); + pMixerMenu->addSeparator(); addDeckAndSamplerControl("pfl", tr("Headphone Listen"), tr("Headphone listen (pfl) button"), - mixerMenu); + pMixerMenu); addSeparator(); // Transport - QMenu* transportMenu = addSubmenu(tr("Transport")); - addDeckAndSamplerAndPreviewDeckControl("play", tr("Play"), tr("Play button"), transportMenu); - addDeckAndSamplerAndPreviewDeckControl("back", tr("Fast Rewind"), tr("Fast Rewind button"), transportMenu); - addDeckAndSamplerAndPreviewDeckControl("fwd", tr("Fast Forward"), tr("Fast Forward button"), transportMenu); + QMenu* pTransportMenu = addSubmenu(tr("Transport")); + addDeckAndSamplerAndPreviewDeckControl("play", tr("Play"), tr("Play button"), pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("back", + tr("Fast Rewind"), + tr("Fast Rewind button"), + pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("fwd", + tr("Fast Forward"), + tr("Fast Forward button"), + pTransportMenu); addDeckAndSamplerAndPreviewDeckControl("playposition", tr("Strip Search"), tr("Strip-search through track"), - transportMenu); - addDeckAndSamplerAndPreviewDeckControl("reverse", tr("Play Reverse"), tr("Play Reverse button"), transportMenu); + pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("reverse", + tr("Play Reverse"), + tr("Play Reverse button"), + pTransportMenu); addDeckAndSamplerAndPreviewDeckControl("reverseroll", tr("Reverse Roll (Censor)"), tr("Reverse roll (Censor) button"), - transportMenu); - addDeckAndSamplerAndPreviewDeckControl("start", tr("Jump To Start"), tr("Jumps to start of track"), transportMenu); + pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("start", + tr("Jump To Start"), + tr("Jumps to start of track"), + pTransportMenu); addDeckAndSamplerAndPreviewDeckControl("start_play", tr("Play From Start"), tr("Jump to start of track and play"), - transportMenu); - addDeckAndSamplerAndPreviewDeckControl("stop", tr("Stop"), tr("Stop button"), transportMenu); + pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("stop", tr("Stop"), tr("Stop button"), pTransportMenu); addDeckAndSamplerAndPreviewDeckControl("start_stop", tr("Stop And Jump To Start"), tr("Stop playback and jump to start of track"), - transportMenu); - addDeckAndSamplerAndPreviewDeckControl("end", tr("Jump To End"), tr("Jump to end of track"), transportMenu); - transportMenu->addSeparator(); + pTransportMenu); + addDeckAndSamplerAndPreviewDeckControl("end", + tr("Jump To End"), + tr("Jump to end of track"), + pTransportMenu); + pTransportMenu->addSeparator(); addDeckAndSamplerAndPreviewDeckControl("eject", tr("Eject"), tr("Eject or un-eject track, i.e. reload the last-ejected track " "(of any deck)
" "Double-press to reload the last replaced track. In empty decks " "it reloads the second-last ejected track."), - transportMenu); - addDeckAndSamplerControl("repeat", tr("Repeat Mode"), tr("Toggle repeat mode"), transportMenu); - addDeckAndSamplerControl("slip_enabled", tr("Slip Mode"), tr("Toggle slip mode"), transportMenu); + pTransportMenu); + addDeckAndSamplerControl("repeat", tr("Repeat Mode"), tr("Toggle repeat mode"), pTransportMenu); + addDeckAndSamplerControl("slip_enabled", + tr("Slip Mode"), + tr("Toggle slip mode"), + pTransportMenu); // BPM / Beatgrid - QMenu* bpmMenu = addSubmenu(tr("BPM / Beatgrid")); - addDeckAndSamplerControl("bpm", tr("BPM"), tr("BPM"), bpmMenu, true); - addDeckAndSamplerControl("bpm_up", tr("BPM +1"), tr("Increase BPM by 1"), bpmMenu); - addDeckAndSamplerControl("bpm_down", tr("BPM -1"), tr("Decrease BPM by 1"), bpmMenu); - addDeckAndSamplerControl("bpm_up_small", tr("BPM +0.1"), tr("Increase BPM by 0.1"), bpmMenu); - addDeckAndSamplerControl("bpm_down_small", tr("BPM -0.1"), tr("Decrease BPM by 0.1"), bpmMenu); - addDeckAndSamplerControl("bpm_tap", tr("BPM Tap"), tr("BPM tap button"), bpmMenu); - bpmMenu->addSeparator(); - addDeckAndSamplerControl("beats_adjust_faster", tr("Adjust Beatgrid Faster +.01"), tr("Increase track's average BPM by 0.01"), bpmMenu); - addDeckAndSamplerControl("beats_adjust_slower", tr("Adjust Beatgrid Slower -.01"), tr("Decrease track's average BPM by 0.01"), bpmMenu); - addDeckAndSamplerControl("beats_translate_earlier", tr("Move Beatgrid Earlier"), tr("Adjust the beatgrid to the left"), bpmMenu); - addDeckAndSamplerControl("beats_translate_later", tr("Move Beatgrid Later"), tr("Adjust the beatgrid to the right"), bpmMenu); + QMenu* pBpmMenu = addSubmenu(tr("BPM / Beatgrid")); + addDeckAndSamplerControl("bpm", tr("BPM"), tr("BPM"), pBpmMenu, true); + addDeckAndSamplerControl("bpm_up", tr("BPM +1"), tr("Increase BPM by 1"), pBpmMenu); + addDeckAndSamplerControl("bpm_down", tr("BPM -1"), tr("Decrease BPM by 1"), pBpmMenu); + addDeckAndSamplerControl("bpm_up_small", tr("BPM +0.1"), tr("Increase BPM by 0.1"), pBpmMenu); + addDeckAndSamplerControl("bpm_down_small", tr("BPM -0.1"), tr("Decrease BPM by 0.1"), pBpmMenu); + addDeckAndSamplerControl("bpm_tap", tr("BPM Tap"), tr("BPM tap button"), pBpmMenu); + pBpmMenu->addSeparator(); + addDeckAndSamplerControl("beats_adjust_faster", + tr("Adjust Beatgrid Faster +.01"), + tr("Increase track's average BPM by 0.01"), + pBpmMenu); + addDeckAndSamplerControl("beats_adjust_slower", + tr("Adjust Beatgrid Slower -.01"), + tr("Decrease track's average BPM by 0.01"), + pBpmMenu); + addDeckAndSamplerControl("beats_translate_earlier", + tr("Move Beatgrid Earlier"), + tr("Adjust the beatgrid to the left"), + pBpmMenu); + addDeckAndSamplerControl("beats_translate_later", + tr("Move Beatgrid Later"), + tr("Adjust the beatgrid to the right"), + pBpmMenu); addDeckControl("beats_translate_curpos", tr("Adjust Beatgrid"), tr("Align beatgrid to current position"), - bpmMenu); + pBpmMenu); addDeckControl("beats_translate_match_alignment", tr("Adjust Beatgrid - Match Alignment"), tr("Adjust beatgrid to match another playing deck."), - bpmMenu); - bpmMenu->addSeparator(); - addDeckAndSamplerControl("quantize", tr("Quantize Mode"), tr("Toggle quantize mode"), bpmMenu); + pBpmMenu); + pBpmMenu->addSeparator(); + addDeckAndSamplerControl("quantize", tr("Quantize Mode"), tr("Toggle quantize mode"), pBpmMenu); - QMenu* syncMenu = addSubmenu(tr("Sync")); + QMenu* pSyncMenu = addSubmenu(tr("Sync")); addDeckAndSamplerControl("sync_enabled", tr("Sync / Sync Lock"), tr("Tap to sync tempo (and phase with quantize enabled), hold to " "enable permanent sync"), - syncMenu); + pSyncMenu); addDeckAndSamplerControl("beatsync", tr("Beat Sync One-Shot"), tr("One-time beat sync tempo (and phase with quantize enabled)"), - syncMenu); + pSyncMenu); addDeckAndSamplerControl("beatsync_tempo", tr("Sync Tempo One-Shot"), tr("One-time beat sync (tempo only)"), - syncMenu); + pSyncMenu); addDeckAndSamplerControl("beatsync_phase", tr("Sync Phase One-Shot"), tr("One-time beat sync (phase only)"), - syncMenu); - syncMenu->addSeparator(); + pSyncMenu); + pSyncMenu->addSeparator(); addControl("[InternalClock]", "sync_leader", tr("Internal Sync Leader"), tr("Toggle Internal Sync Leader"), - syncMenu); + pSyncMenu); addControl("[InternalClock]", "bpm", tr("Internal Leader BPM"), tr("Internal Leader BPM"), - syncMenu); + pSyncMenu); addControl("[InternalClock]", "bpm_up", tr("Internal Leader BPM +1"), tr("Increase internal Leader BPM by 1"), - syncMenu); + pSyncMenu); addControl("[InternalClock]", "bpm_down", tr("Internal Leader BPM -1"), tr("Decrease internal Leader BPM by 1"), - syncMenu); + pSyncMenu); addControl("[InternalClock]", "bpm_up_small", tr("Internal Leader BPM +0.1"), tr("Increase internal Leader BPM by 0.1"), - syncMenu); + pSyncMenu); addControl("[InternalClock]", "bpm_down_small", tr("Internal Leader BPM -0.1"), tr("Decrease internal Leader BPM by 0.1"), - syncMenu); - syncMenu->addSeparator(); + pSyncMenu); + pSyncMenu->addSeparator(); addDeckAndSamplerControl("sync_leader", tr("Sync Leader"), tr("Sync mode 3-state toggle / indicator (Off, Soft Leader, " "Explicit Leader)"), - syncMenu); + pSyncMenu); // Speed - QMenu* speedMenu = addSubmenu(tr("Speed")); + QMenu* pSpeedMenu = addSubmenu(tr("Speed")); addDeckAndSamplerControl("rate", tr("Playback Speed"), tr("Playback speed control (Vinyl \"Pitch\" slider)"), - speedMenu, + pSpeedMenu, true); - speedMenu->addSeparator(); + pSpeedMenu->addSeparator(); addDeckAndSamplerControl("rate_perm_up", tr("Increase Speed"), tr("Adjust speed faster (coarse)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_perm_up_small", tr("Increase Speed (Fine)"), tr("Adjust speed faster (fine)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_perm_down", tr("Decrease Speed"), tr("Adjust speed slower (coarse)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_perm_down_small", tr("Decrease Speed (Fine)"), tr("Adjust speed slower (fine)"), - speedMenu); - speedMenu->addSeparator(); + pSpeedMenu); + pSpeedMenu->addSeparator(); addDeckAndSamplerControl("rate_temp_up", tr("Temporarily Increase Speed"), tr("Temporarily increase speed (coarse)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_temp_up_small", tr("Temporarily Increase Speed (Fine)"), tr("Temporarily increase speed (fine)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_temp_down", tr("Temporarily Decrease Speed"), tr("Temporarily decrease speed (coarse)"), - speedMenu); + pSpeedMenu); addDeckAndSamplerControl("rate_temp_down_small", tr("Temporarily Decrease Speed (Fine)"), tr("Temporarily decrease speed (fine)"), - speedMenu); + pSpeedMenu); // Pitch (Musical Key) - QMenu* pitchMenu = addSubmenu(tr("Pitch (Musical Key)")); + QMenu* pPitchMenu = addSubmenu(tr("Pitch (Musical Key)")); addDeckAndSamplerControl("pitch", tr("Pitch (Musical key)"), tr("Pitch control (does not affect tempo), center is original " "pitch"), - pitchMenu, + pPitchMenu, true); addDeckAndSamplerControl("pitch_up", tr("Increase Pitch"), tr("Increases the pitch by one semitone"), - pitchMenu); + pPitchMenu); addDeckAndSamplerControl("pitch_up_small", tr("Increase Pitch (Fine)"), tr("Increases the pitch by 10 cents"), - pitchMenu); + pPitchMenu); addDeckAndSamplerControl("pitch_down", tr("Decrease Pitch"), tr("Decreases the pitch by one semitone"), - pitchMenu); + pPitchMenu); addDeckAndSamplerControl("pitch_down_small", tr("Decrease Pitch (Fine)"), tr("Decreases the pitch by 10 cents"), - pitchMenu); + pPitchMenu); addDeckAndSamplerControl("pitch_adjust", tr("Pitch Adjust"), tr("Adjust pitch from speed slider pitch"), - pitchMenu, + pPitchMenu, true); - pitchMenu->addSeparator(); - addDeckAndSamplerControl("sync_key", tr("Match Key"), tr("Match musical key"), pitchMenu); - addDeckAndSamplerControl("reset_key", tr("Reset Key"), tr("Resets key to original"), pitchMenu); - addDeckAndSamplerControl("keylock", tr("Keylock"), tr("Toggle keylock mode"), pitchMenu); + pPitchMenu->addSeparator(); + addDeckAndSamplerControl("sync_key", tr("Match Key"), tr("Match musical key"), pPitchMenu); + addDeckAndSamplerControl("reset_key", + tr("Reset Key"), + tr("Resets key to original"), + pPitchMenu); + addDeckAndSamplerControl("keylock", tr("Keylock"), tr("Toggle keylock mode"), pPitchMenu); // Vinyl Control - QMenu* vinylControlMenu = addSubmenu(tr("Vinyl Control")); + QMenu* pVinylControlMenu = addSubmenu(tr("Vinyl Control")); addDeckControl("vinylcontrol_enabled", tr("Toggle Vinyl Control"), tr("Toggle Vinyl Control (ON/OFF)"), - vinylControlMenu); + pVinylControlMenu); addDeckControl("vinylcontrol_mode", tr("Vinyl Control Mode"), tr("Toggle vinyl-control mode (ABS/REL/CONST)"), - vinylControlMenu); + pVinylControlMenu); addDeckControl("vinylcontrol_cueing", tr("Vinyl Control Cueing Mode"), tr("Toggle vinyl-control cueing mode (OFF/ONE/HOT)"), - vinylControlMenu); + pVinylControlMenu); addDeckControl("passthrough", tr("Vinyl Control Passthrough"), tr("Pass through external audio into the internal mixer"), - vinylControlMenu); + pVinylControlMenu); addControl(VINYL_PREF_KEY, "Toggle", tr("Vinyl Control Next Deck"), tr("Single deck mode - Switch vinyl control to next deck"), - vinylControlMenu); + pVinylControlMenu); // Cues - QMenu* cueMenu = addSubmenu(tr("Cues")); - addDeckControl("cue_default", tr("Cue"), tr("Cue button"), cueMenu); - addDeckControl("cue_set", tr("Set Cue"), tr("Set cue point"), cueMenu); - addDeckControl("cue_goto", tr("Go-To Cue"), tr("Go to cue point"), cueMenu); + QMenu* pCueMenu = addSubmenu(tr("Cues")); + addDeckControl("cue_default", tr("Cue"), tr("Cue button"), pCueMenu); + addDeckControl("cue_set", tr("Set Cue"), tr("Set cue point"), pCueMenu); + addDeckControl("cue_goto", tr("Go-To Cue"), tr("Go to cue point"), pCueMenu); addDeckAndSamplerAndPreviewDeckControl("cue_gotoandplay", tr("Go-To Cue And Play"), tr("Go to cue point and play"), - cueMenu); + pCueMenu); addDeckControl("cue_gotoandstop", tr("Go-To Cue And Stop"), tr("Go to cue point and stop"), - cueMenu); - addDeckControl("cue_preview", tr("Preview Cue"), tr("Preview from cue point"), cueMenu); - addDeckControl("cue_cdj", tr("Cue (CDJ Mode)"), tr("Cue button (CDJ mode)"), cueMenu); - addDeckControl("play_stutter", tr("Stutter Cue"), tr("Stutter cue"), cueMenu); + pCueMenu); + addDeckControl("cue_preview", tr("Preview Cue"), tr("Preview from cue point"), pCueMenu); + addDeckControl("cue_cdj", tr("Cue (CDJ Mode)"), tr("Cue button (CDJ mode)"), pCueMenu); + addDeckControl("play_stutter", tr("Stutter Cue"), tr("Stutter cue"), pCueMenu); addDeckControl("cue_play", tr("CUP (Cue + Play)"), tr("Go to cue point and play after release"), - cueMenu); + pCueMenu); // Hotcues - QMenu* hotcueMainMenu = addSubmenu(tr("Hotcues")); + QMenu* pHotcueMainMenu = addSubmenu(tr("Hotcues")); QString hotcueActivateTitle = tr("Hotcue %1"); QString hotcueClearTitle = tr("Clear Hotcue %1"); QString hotcueSetTitle = tr("Set Hotcue %1"); @@ -438,74 +471,74 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) addDeckControl("shift_cues_earlier", tr("Shift cue points earlier"), tr("Shift cue points 10 milliseconds earlier"), - hotcueMainMenu); + pHotcueMainMenu); addDeckControl("shift_cues_earlier_small", tr("Shift cue points earlier (fine)"), tr("Shift cue points 1 millisecond earlier"), - hotcueMainMenu); + pHotcueMainMenu); addDeckControl("shift_cues_later", tr("Shift cue points later"), tr("Shift cue points 10 milliseconds later"), - hotcueMainMenu); + pHotcueMainMenu); addDeckControl("shift_cues_later_small", tr("Shift cue points later (fine)"), tr("Shift cue points 1 millisecond later"), - hotcueMainMenu); + pHotcueMainMenu); // add menus for hotcues 1-16. // though, keep the menu small put additional hotcues in a separate menu, // but don't create that submenu for less than 4 additional hotcues. int preferredHotcuesVisible = 16; int moreMenuThreshold = 4; - QMenu* parentMenu = hotcueMainMenu; - QMenu* hotcueMoreMenu = nullptr; + QMenu* pParentMenu = pHotcueMainMenu; + QMenu* pHotcueMoreMenu = nullptr; bool moreHotcues = NUM_HOT_CUES >= preferredHotcuesVisible + moreMenuThreshold; if (moreHotcues) { // populate menu here, add it below #preferredHotcuesVisible - hotcueMoreMenu = new QMenu( + pHotcueMoreMenu = new QMenu( tr("Hotcues %1-%2").arg(preferredHotcuesVisible + 1).arg(NUM_HOT_CUES), - hotcueMainMenu); + pHotcueMainMenu); } for (int i = 1; i <= NUM_HOT_CUES; ++i) { if (moreHotcues && i > preferredHotcuesVisible) { - parentMenu = hotcueMoreMenu; + pParentMenu = pHotcueMoreMenu; } - QMenu* hotcueSubMenu = addSubmenu(tr("Hotcue %1").arg(QString::number(i)), parentMenu); + QMenu* pHotcueSubMenu = addSubmenu(tr("Hotcue %1").arg(QString::number(i)), pParentMenu); addDeckAndSamplerControl(QString("hotcue_%1_activate").arg(i), hotcueActivateTitle.arg(QString::number(i)), hotcueActivateDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_clear").arg(i), hotcueClearTitle.arg(QString::number(i)), hotcueClearDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_set").arg(i), hotcueSetTitle.arg(QString::number(i)), hotcueSetDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_goto").arg(i), hotcueGotoTitle.arg(QString::number(i)), hotcueGotoDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_gotoandstop").arg(i), hotcueGotoAndStopTitle.arg(QString::number(i)), hotcueGotoAndStopDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_gotoandplay").arg(i), hotcueGotoAndPlayTitle.arg(QString::number(i)), hotcueGotoAndPlayDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); addDeckAndSamplerControl(QString("hotcue_%1_activate_preview").arg(i), hotcuePreviewTitle.arg(QString::number(i)), hotcuePreviewDescription.arg(QString::number(i)), - hotcueSubMenu); + pHotcueSubMenu); } if (moreHotcues) { - hotcueMainMenu->addSeparator(); - hotcueMainMenu->addMenu(hotcueMoreMenu); + pHotcueMainMenu->addSeparator(); + pHotcueMainMenu->addMenu(pHotcueMoreMenu); } // Intro/outro range markers - QMenu* introOutroMenu = addSubmenu(tr("Intro / Outro Markers")); + QMenu* pIntroOutroMenu = addSubmenu(tr("Intro / Outro Markers")); const QStringList markerTitles = { tr("Intro Start Marker"), tr("Intro End Marker"), @@ -523,26 +556,26 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) "outro_end"}; for (int i = 0; i < markerTitles.size(); ++i) { - QMenu* tempMenu = addSubmenu(markerTitles[i], introOutroMenu); + QMenu* pTempMenu = addSubmenu(markerTitles[i], pIntroOutroMenu); addDeckAndSamplerAndPreviewDeckControl( QString("%1_activate").arg(markerCOs[i]), tr("Activate %1", "[intro/outro marker").arg(markerTitles[i]), tr("Jump to or set the %1", "[intro/outro marker").arg(markerNames[i]), - tempMenu); + pTempMenu); addDeckAndSamplerAndPreviewDeckControl( QString("%1_set").arg(markerCOs[i]), tr("Set %1", "[intro/outro marker").arg(markerTitles[i]), tr("Set or jump to the %1", "[intro/outro marker").arg(markerNames[i]), - tempMenu); + pTempMenu); addDeckAndSamplerAndPreviewDeckControl( QString("%1_clear").arg(markerCOs[i]), tr("Clear %1", "[intro/outro marker").arg(markerTitles[i]), tr("Clear the %1", "[intro/outro marker").arg(markerNames[i]), - tempMenu); + pTempMenu); } // Loops - QMenu* loopMenu = addSubmenu(tr("Looping")); + QMenu* pLoopMenu = addSubmenu(tr("Looping")); // add beatloop_activate and beatlooproll_activate to both the // Loop and Beat-Loop menus to make sure users can find them. QString beatloopActivateTitle = tr("Loop Selected Beats"); @@ -574,59 +607,69 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) addDeckControl("beatloop_activate", beatloopActivateTitle, beatloopActivateDescription, - loopMenu); - QMenu* loopActivateMenu = addSubmenu(tr("Loop Beats"), loopMenu); + pLoopMenu); + QMenu* pLoopActivateMenu = addSubmenu(tr("Loop Beats"), pLoopMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("beatloop_%1_toggle").arg(beats), beatLoopTitle.arg(humanBeats), beatLoopDescription.arg(humanBeats), - loopActivateMenu); + pLoopActivateMenu); } - loopMenu->addSeparator(); + pLoopMenu->addSeparator(); addDeckControl("beatlooproll_activate", beatloopRollActivateTitle, beatloopRollActivateDescription, - loopMenu); - QMenu* looprollActivateMenu = addSubmenu(tr("Loop Roll Beats"), loopMenu); + pLoopMenu); + QMenu* pLooprollActivateMenu = addSubmenu(tr("Loop Roll Beats"), pLoopMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("beatlooproll_%1_activate").arg(beats), beatLoopRollTitle.arg(humanBeats), beatLoopRollDescription.arg(humanBeats), - looprollActivateMenu); + pLooprollActivateMenu); } - loopMenu->addSeparator(); + pLoopMenu->addSeparator(); - addDeckControl("loop_in", tr("Loop In"), tr("Loop In button"), loopMenu); - addDeckControl("loop_in_goto", tr("Go To Loop In"), tr("Go to Loop In button"), loopMenu); - addDeckControl("loop_out", tr("Loop Out"), tr("Loop Out button"), loopMenu); - addDeckControl("loop_out_goto", tr("Go To Loop Out"), tr("Go to Loop Out button"), loopMenu); - addDeckControl("loop_exit", tr("Loop Exit"), tr("Loop Exit button"), loopMenu); + addDeckControl("loop_in", tr("Loop In"), tr("Loop In button"), pLoopMenu); + addDeckControl("loop_in_goto", tr("Go To Loop In"), tr("Go to Loop In button"), pLoopMenu); + addDeckControl("loop_out", tr("Loop Out"), tr("Loop Out button"), pLoopMenu); + addDeckControl("loop_out_goto", tr("Go To Loop Out"), tr("Go to Loop Out button"), pLoopMenu); + addDeckControl("loop_exit", tr("Loop Exit"), tr("Loop Exit button"), pLoopMenu); addDeckControl("reloop_toggle", tr("Reloop/Exit Loop"), tr("Toggle loop on/off and jump to Loop In point if loop is behind " "play position"), - loopMenu); + pLoopMenu); addDeckControl("reloop_andstop", tr("Reloop And Stop"), tr("Enable loop, jump to Loop In point, and stop"), - loopMenu); - addDeckControl("loop_halve", tr("Loop Halve"), tr("Halve the loop length"), loopMenu); - addDeckControl("loop_double", tr("Loop Double"), tr("Double the loop length"), loopMenu); + pLoopMenu); + addDeckControl("loop_halve", tr("Loop Halve"), tr("Halve the loop length"), pLoopMenu); + addDeckControl("loop_double", tr("Loop Double"), tr("Double the loop length"), pLoopMenu); // Beat Jump / Loop Move - QMenu* beatJumpMenu = addSubmenu(tr("Beat Jump / Loop Move")); + QMenu* pBeatJumpMenu = addSubmenu(tr("Beat Jump / Loop Move")); QString beatJumpForwardTitle = tr("Jump / Move Loop Forward %1 Beats"); QString beatJumpBackwardTitle = tr("Jump / Move Loop Backward %1 Beats"); QString beatJumpForwardDescription = tr("Jump forward by %1 beats, or if a loop is enabled, move the loop forward %1 beats"); QString beatJumpBackwardDescription = tr("Jump backward by %1 beats, or if a loop is enabled, move the loop backward %1 beats"); - addDeckControl("beatjump_forward", tr("Beat Jump / Loop Move Forward Selected Beats"), tr("Jump forward by the selected number of beats, or if a loop is enabled, move the loop forward by the selected number of beats"), beatJumpMenu); - addDeckControl("beatjump_backward", tr("Beat Jump / Loop Move Backward Selected Beats"), tr("Jump backward by the selected number of beats, or if a loop is enabled, move the loop backward by the selected number of beats"), beatJumpMenu); - beatJumpMenu->addSeparator(); - - QMenu* beatjumpFwdSubmenu = addSubmenu(tr("Beat Jump / Loop Move Forward"), beatJumpMenu); + addDeckControl("beatjump_forward", + tr("Beat Jump / Loop Move Forward Selected Beats"), + tr("Jump forward by the selected number of beats, or if a loop is " + "enabled, move the loop forward by the selected number of " + "beats"), + pBeatJumpMenu); + addDeckControl("beatjump_backward", + tr("Beat Jump / Loop Move Backward Selected Beats"), + tr("Jump backward by the selected number of beats, or if a loop is " + "enabled, move the loop backward by the selected number of " + "beats"), + pBeatJumpMenu); + pBeatJumpMenu->addSeparator(); + + QMenu* beatjumpFwdSubmenu = addSubmenu(tr("Beat Jump / Loop Move Forward"), pBeatJumpMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("beatjump_%1_forward").arg(beats), @@ -635,7 +678,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) beatjumpFwdSubmenu); } - QMenu* beatjumpBwdSubmenu = addSubmenu(tr("Beat Jump / Loop Move Backward"), beatJumpMenu); + QMenu* beatjumpBwdSubmenu = addSubmenu(tr("Beat Jump / Loop Move Backward"), pBeatJumpMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("beatjump_%1_backward").arg(beats), @@ -650,175 +693,175 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) QString loopMoveForwardDescription = tr("Move loop forward by %1 beats"); QString loopMoveBackwardDescription = tr("Move loop backward by %1 beats"); - QMenu* loopmoveFwdSubmenu = addSubmenu(tr("Loop Move Forward"), beatJumpMenu); + QMenu* pLoopmoveFwdSubmenu = addSubmenu(tr("Loop Move Forward"), pBeatJumpMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("loop_move_%1_forward").arg(beats), loopMoveForwardTitle.arg(humanBeats), loopMoveForwardDescription.arg(humanBeats), - loopmoveFwdSubmenu); + pLoopmoveFwdSubmenu); } - QMenu* loopmoveBwdSubmenu = addSubmenu(tr("Loop Move Backward"), beatJumpMenu); + QMenu* pLoopmoveBwdSubmenu = addSubmenu(tr("Loop Move Backward"), pBeatJumpMenu); foreach (double beats, beatSizes) { QString humanBeats = humanBeatSizes.value(beats, QString::number(beats)); addDeckControl(QString("loop_move_%1_backward").arg(beats), loopMoveBackwardTitle.arg(humanBeats), loopMoveBackwardDescription.arg(humanBeats), - loopmoveBwdSubmenu); + pLoopmoveBwdSubmenu); } addDeckControl("loop_remove", tr("Remove Temporary Loop"), tr("Remove the temporary loop"), - loopMenu); + pLoopMenu); addSeparator(); // Library Controls - QMenu* libraryMenu = addSubmenu(m_libraryStr); - QMenu* navigationMenu = addSubmenu(tr("Navigation"), libraryMenu); + QMenu* pLibraryMenu = addSubmenu(m_libraryStr); + QMenu* pNavigationMenu = addSubmenu(tr("Navigation"), pLibraryMenu); addLibraryControl("MoveUp", tr("Move up"), tr("Equivalent to pressing the UP key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveDown", tr("Move down"), tr("Equivalent to pressing the DOWN key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveVertical", tr("Move up/down"), tr("Move vertically in either direction using a knob, as if " "pressing UP/DOWN keys"), - navigationMenu); + pNavigationMenu); addLibraryControl("ScrollUp", tr("Scroll Up"), tr("Equivalent to pressing the PAGE UP key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("ScrollDown", tr("Scroll Down"), tr("Equivalent to pressing the PAGE DOWN key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("ScrollVertical", tr("Scroll up/down"), tr("Scroll vertically in either direction using a knob, as if " "pressing PGUP/PGDOWN keys"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveLeft", tr("Move left"), tr("Equivalent to pressing the LEFT key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveRight", tr("Move right"), tr("Equivalent to pressing the RIGHT key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveHorizontal", tr("Move left/right"), tr("Move horizontally in either direction using a knob, as if " "pressing LEFT/RIGHT keys"), - navigationMenu); - navigationMenu->addSeparator(); + pNavigationMenu); + pNavigationMenu->addSeparator(); addLibraryControl("MoveFocusForward", tr("Move focus to right pane"), tr("Equivalent to pressing the TAB key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveFocusBackward", tr("Move focus to left pane"), tr("Equivalent to pressing the SHIFT+TAB key on the keyboard"), - navigationMenu); + pNavigationMenu); addLibraryControl("MoveFocus", tr("Move focus to right/left pane"), tr("Move focus one pane to right or left using a knob, as if " "pressing TAB/SHIFT+TAB keys"), - navigationMenu); + pNavigationMenu); addLibraryControl("sort_focused_column", tr("Sort focused column"), tr("Sort the column of the cell that is currently focused, " "equivalent to clicking on its header"), - navigationMenu); + pNavigationMenu); - libraryMenu->addSeparator(); + pLibraryMenu->addSeparator(); addLibraryControl("GoToItem", tr("Go to the currently selected item"), tr("Choose the currently selected item and advance forward one " "pane if appropriate"), - libraryMenu); + pLibraryMenu); // Load track (these can be loaded into any channel) addDeckAndSamplerControl("LoadSelectedTrack", tr("Load Track"), tr("Load selected track"), - libraryMenu); + pLibraryMenu); addDeckAndSamplerAndPreviewDeckControl("LoadSelectedTrackAndPlay", tr("Load Track and Play"), tr("Load selected track and play"), - libraryMenu); - libraryMenu->addSeparator(); + pLibraryMenu); + pLibraryMenu->addSeparator(); // Auto DJ addLibraryControl("AutoDjAddBottom", tr("Add to Auto DJ Queue (bottom)"), tr("Append the selected track to the Auto DJ Queue"), - libraryMenu); + pLibraryMenu); addLibraryControl("AutoDjAddTop", tr("Add to Auto DJ Queue (top)"), tr("Prepend selected track to the Auto DJ Queue"), - libraryMenu); + pLibraryMenu); addLibraryControl("AutoDjAddReplace", tr("Add to Auto DJ Queue (replace)"), tr("Replace Auto DJ Queue with selected tracks"), - libraryMenu); - libraryMenu->addSeparator(); + pLibraryMenu); + pLibraryMenu->addSeparator(); // Search box addLibraryControl("search_history_next", tr("Select next search history"), tr("Selects the next search history entry"), - libraryMenu); + pLibraryMenu); addLibraryControl("search_history_prev", tr("Select previous search history"), tr("Selects the previous search history entry"), - libraryMenu); + pLibraryMenu); addLibraryControl("search_history_selector", tr("Move selected search entry"), tr("Moves the selected search history item into given direction " "and steps"), - libraryMenu); + pLibraryMenu); addLibraryControl("clear_search", tr("Clear search"), tr("Clears the search query"), - libraryMenu); + pLibraryMenu); - libraryMenu->addSeparator(); + pLibraryMenu->addSeparator(); addControl("[Recording]", "toggle_recording", tr("Record Mix"), tr("Toggle mix recording"), - libraryMenu, + pLibraryMenu, false, m_libraryStr); // Effect Controls - QMenu* effectsMenu = addSubmenu(tr("Effects")); + QMenu* pEffectsMenu = addSubmenu(tr("Effects")); // Quick Effect Rack COs - QMenu* quickEffectMenu = addSubmenu(tr("Quick Effects"), effectsMenu); + QMenu* pQuickEffectMenu = addSubmenu(tr("Quick Effects"), pEffectsMenu); for (int i = 1; i <= iNumDecks; ++i) { addControl(QString("[QuickEffectRack1_[Channel%1]]").arg(i), "super1", tr("Deck %1 Quick Effect Super Knob").arg(i), tr("Quick Effect Super Knob (control linked effect " "parameters)"), - quickEffectMenu, + pQuickEffectMenu, false, tr("Quick Effect")); addControl(QString("[QuickEffectRack1_[Channel%1]_Effect1]").arg(i), "enabled", tr("Deck %1 Quick Effect Enable Button").arg(i), tr("Quick Effect Enable Button"), - quickEffectMenu, + pQuickEffectMenu, false, tr("Quick Effect")); } - effectsMenu->addSeparator(); + pEffectsMenu->addSeparator(); for (int iEffectUnitNumber = 1; iEffectUnitNumber <= kNumStandardEffectUnits; ++iEffectUnitNumber) { @@ -827,20 +870,20 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) const QString descriptionPrefix = QString("%1").arg(m_effectUnitStr.arg(iEffectUnitNumber)); - QMenu* effectUnitMenu = addSubmenu(m_effectUnitStr.arg(iEffectUnitNumber), - effectsMenu); + QMenu* pEffectUnitMenu = addSubmenu(m_effectUnitStr.arg(iEffectUnitNumber), + pEffectsMenu); addControl(effectUnitGroup, "clear", tr("Clear Unit"), tr("Clear effect unit"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, "enabled", tr("Toggle Unit"), tr("Enable or disable effect processing"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, @@ -848,56 +891,56 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Dry/Wet"), tr("Adjust the balance between the original (dry) and " "processed (wet) signal."), - effectUnitMenu, + pEffectUnitMenu, true, descriptionPrefix); addControl(effectUnitGroup, "super1", tr("Super Knob"), tr("Super Knob (control effects' Meta Knobs)"), - effectUnitMenu, + pEffectUnitMenu, true, descriptionPrefix); addControl(effectUnitGroup, "mix_mode", tr("Mix Mode Toggle"), tr("Toggle effect unit between D/W and D+W modes"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, "next_chain", tr("Next Chain"), tr("Next chain preset"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, "prev_chain", tr("Previous Chain"), tr("Previous chain preset"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, "chain_selector", tr("Next/Previous Chain"), tr("Next or previous chain preset"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); addControl(effectUnitGroup, "show_parameters", tr("Show Effect Parameters"), tr("Show Effect Parameters"), - effectUnitMenu, + pEffectUnitMenu, false, descriptionPrefix); QString assignMenuTitle = tr("Effect Unit Assignment"); QString assignString = tr("Assign "); - QMenu* effectUnitGroups = addSubmenu(assignMenuTitle, - effectUnitMenu); + QMenu* pEffectUnitGroupsMenu = addSubmenu(assignMenuTitle, + pEffectUnitMenu); QString groupDescriptionPrefix = QString("%1").arg( m_effectUnitStr.arg(iEffectUnitNumber)); @@ -905,14 +948,14 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) addControl(effectUnitGroup, "group_[Master]_enable", assignString + m_effectMainOutputStr, // in ComboBox assignString + m_effectMainOutputStr, // description below - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); addControl(effectUnitGroup, "group_[Headphone]_enable", assignString + m_effectHeadphoneOutputStr, assignString + m_effectHeadphoneOutputStr, - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); @@ -924,7 +967,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) QString("group_%1_enable").arg(playerGroup), assignString + m_deckStr.arg(iDeckNumber), assignString + m_deckStr.arg(iDeckNumber), - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); } @@ -940,7 +983,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) QString("group_%1_enable").arg(playerGroup), assignString + m_samplerStr.arg(iSamplerNumber), assignString + m_samplerStr.arg(iSamplerNumber), - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); } @@ -955,7 +998,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) QString("group_%1_enable").arg(micGroup), assignString + m_microphoneStr.arg(iMicrophoneNumber), assignString + m_microphoneStr.arg(iMicrophoneNumber), - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); } @@ -970,7 +1013,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) QString("group_%1_enable").arg(auxGroup), assignString + m_auxStr.arg(iAuxiliaryNumber), assignString + m_auxStr.arg(iAuxiliaryNumber), - effectUnitGroups, + pEffectUnitGroupsMenu, false, groupDescriptionPrefix); } @@ -983,8 +1026,8 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) StandardEffectChain::formatEffectSlotGroup( iEffectUnitNumber - 1, iEffectSlotNumber - 1); - QMenu* effectSlotMenu = addSubmenu(m_effectStr.arg(iEffectSlotNumber), - effectUnitMenu); + QMenu* pEffectSlotMenu = addSubmenu(m_effectStr.arg(iEffectSlotNumber), + pEffectUnitMenu); QString slotDescriptionPrefix = QString("%1, %2").arg(descriptionPrefix, @@ -994,42 +1037,42 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) "clear", tr("Clear"), tr("Clear the current effect"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); addControl(effectSlotGroup, "meta", tr("Meta Knob"), tr("Effect Meta Knob (control linked effect parameters)"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); addControl(effectSlotGroup, "enabled", tr("Toggle"), tr("Toggle the current effect"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); addControl(effectSlotGroup, "next_effect", tr("Next"), tr("Switch to next effect"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); addControl(effectSlotGroup, "prev_effect", tr("Previous"), tr("Switch to the previous effect"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); addControl(effectSlotGroup, "effect_selector", tr("Next or Previous"), tr("Switch to either next or previous effect"), - effectSlotMenu, + pEffectSlotMenu, false, slotDescriptionPrefix); @@ -1045,9 +1088,9 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) iEffectUnitNumber - 1, iEffectSlotNumber - 1); const QString parameterSlotItemPrefix = EffectKnobParameterSlot::formatItemPrefix( iParameterSlotNumber - 1); - QMenu* parameterSlotMenu = addSubmenu( + QMenu* pParameterSlotMenu = addSubmenu( m_parameterStr.arg(iParameterSlotNumber), - effectSlotMenu); + pEffectSlotMenu); QString parameterDescriptionPrefix = QString("%1, %2").arg(slotDescriptionPrefix, @@ -1058,7 +1101,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) parameterSlotItemPrefix, tr("Parameter Value"), tr("Parameter Value"), - parameterSlotMenu, + pParameterSlotMenu, true, parameterDescriptionPrefix); addControl(parameterSlotGroup, @@ -1066,7 +1109,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Meta Knob Mode"), tr("Set how linked effect parameters change when " "turning the Meta Knob."), - parameterSlotMenu, + pParameterSlotMenu, false, parameterDescriptionPrefix); addControl(parameterSlotGroup, @@ -1074,7 +1117,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("Meta Knob Mode Invert"), tr("Invert how linked effect parameters change when " "turning the Meta Knob."), - parameterSlotMenu, + pParameterSlotMenu, false, parameterDescriptionPrefix); } @@ -1092,9 +1135,9 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) const QString parameterSlotItemPrefix = EffectButtonParameterSlot::formatItemPrefix( iParameterSlotNumber - 1); - QMenu* parameterSlotMenu = addSubmenu( + QMenu* pParameterSlotMenu = addSubmenu( m_buttonParameterStr.arg(iParameterSlotNumber), - effectSlotMenu); + pEffectSlotMenu); QString parameterDescriptionPrefix = QString("%1, %2").arg(slotDescriptionPrefix, @@ -1105,7 +1148,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) parameterSlotItemPrefix, tr("Button Parameter Value"), tr("Button Parameter Value"), - parameterSlotMenu, + pParameterSlotMenu, true, parameterDescriptionPrefix); } @@ -1113,243 +1156,243 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) } // Microphone Controls - QMenu* microphoneMenu = addSubmenu(tr("Microphone / Auxiliary")); + QMenu* pMicrophoneMenu = addSubmenu(tr("Microphone / Auxiliary")); addMicrophoneAndAuxControl("talkover", tr("Microphone On/Off"), tr("Microphone on/off"), - microphoneMenu, + pMicrophoneMenu, true, false); addControl("[Master]", "duckStrength", tr("Microphone Ducking Strength"), tr("Microphone Ducking Strength"), - microphoneMenu, + pMicrophoneMenu, true); addControl("[Master]", "talkoverDucking", tr("Microphone Ducking Mode"), tr("Toggle microphone ducking mode (OFF, AUTO, MANUAL)"), - microphoneMenu); + pMicrophoneMenu); addMicrophoneAndAuxControl("passthrough", tr("Auxiliary On/Off"), tr("Auxiliary on/off"), - microphoneMenu, + pMicrophoneMenu, false, true); - microphoneMenu->addSeparator(); + pMicrophoneMenu->addSeparator(); addMicrophoneAndAuxControl("pregain", tr("Gain"), tr("Gain knob"), - microphoneMenu, + pMicrophoneMenu, true, true, true); addMicrophoneAndAuxControl("volume", tr("Volume Fader"), tr("Volume Fader"), - microphoneMenu, + pMicrophoneMenu, true, true, true); addMicrophoneAndAuxControl("volume_set_one", tr("Full Volume"), tr("Set to full volume"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("volume_set_zero", tr("Zero Volume"), tr("Set to zero volume"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("mute", tr("Mute"), tr("Mute button"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("pfl", tr("Headphone Listen"), tr("Headphone listen button"), - microphoneMenu, + pMicrophoneMenu, true, true); - microphoneMenu->addSeparator(); + pMicrophoneMenu->addSeparator(); addMicrophoneAndAuxControl("orientation", tr("Orientation"), tr("Mix orientation (e.g. left, right, center)"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("orientation_left", tr("Orient Left"), tr("Set mix orientation to left"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("orientation_center", tr("Orient Center"), tr("Set mix orientation to center"), - microphoneMenu, + pMicrophoneMenu, true, true); addMicrophoneAndAuxControl("orientation_right", tr("Orient Right"), tr("Set mix orientation to right"), - microphoneMenu, + pMicrophoneMenu, true, true); // AutoDJ Controls - QMenu* autodjMenu = addSubmenu(tr("Auto DJ")); + QMenu* pAutodjMenu = addSubmenu(tr("Auto DJ")); addControl("[AutoDJ]", "shuffle_playlist", tr("Auto DJ Shuffle"), tr("Shuffle the content of the Auto DJ queue"), - autodjMenu); + pAutodjMenu); addControl("[AutoDJ]", "skip_next", tr("Auto DJ Skip Next"), tr("Skip the next track in the Auto DJ queue"), - autodjMenu); + pAutodjMenu); addControl("[AutoDJ]", "add_random_track", tr("Auto DJ Add Random Track"), tr("Add a random track to the Auto DJ queue"), - autodjMenu); + pAutodjMenu); addControl("[AutoDJ]", "fade_now", tr("Auto DJ Fade To Next"), tr("Trigger the transition to the next track"), - autodjMenu); + pAutodjMenu); addControl("[AutoDJ]", "enabled", tr("Auto DJ Toggle"), tr("Toggle Auto DJ On/Off"), - autodjMenu); + pAutodjMenu); // Skin Controls - QMenu* guiMenu = addSubmenu(tr("User Interface")); + QMenu* pGuiMenu = addSubmenu(tr("User Interface")); addControl("[Samplers]", "show_samplers", tr("Samplers Show/Hide"), tr("Show/hide the sampler section"), - guiMenu); + pGuiMenu); addControl("[Microphone]", "show_microphone", tr("Microphone & Auxiliary Show/Hide"), tr("Show/hide the microphone & auxiliary section"), - guiMenu); + pGuiMenu); addControl("[PreviewDeck]", "show_previewdeck", tr("Preview Deck Show/Hide"), tr("Show/hide the preview deck"), - guiMenu); + pGuiMenu); addControl("[EffectRack1]", "show", tr("Effect Rack Show/Hide"), tr("Show/hide the effect rack"), - guiMenu); + pGuiMenu); addControl("[Skin]", "show_4effectunits", tr("4 Effect Units Show/Hide"), tr("Switches between showing 2 and 4 effect units"), - guiMenu); + pGuiMenu); addControl("[Skin]", "show_mixer", tr("Mixer Show/Hide"), tr("Show or hide the mixer."), - guiMenu); + pGuiMenu); addControl("[Library]", "show_coverart", tr("Cover Art Show/Hide (Library)"), tr("Show/hide cover art in the library"), - guiMenu); + pGuiMenu); addControl("[Skin]", "show_maximized_library", tr("Library Maximize/Restore"), tr("Maximize the track library to take up all the available screen " "space."), - guiMenu); + pGuiMenu); - guiMenu->addSeparator(); + pGuiMenu->addSeparator(); addControl("[Skin]", "show_4decks", tr("Toggle 4 Decks"), tr("Switches between showing 2 decks and 4 decks."), - guiMenu); + pGuiMenu); addControl("[Skin]", "show_coverart", tr("Cover Art Show/Hide (Decks)"), tr("Show/hide cover art in the main decks"), - guiMenu); + pGuiMenu); addControl(VINYL_PREF_KEY, "show_vinylcontrol", tr("Vinyl Control Show/Hide"), tr("Show/hide the vinyl control section"), - guiMenu); + pGuiMenu); QString spinnyTitle = tr("Vinyl Spinner Show/Hide"); QString spinnyDescription = tr("Show/hide spinning vinyl widget"); - QMenu* spinnyMenu = addSubmenu(spinnyTitle, guiMenu); - guiMenu->addSeparator(); + QMenu* pSpinnyMenu = addSubmenu(spinnyTitle, pGuiMenu); + pGuiMenu->addSeparator(); addControl("[Skin]", "show_spinnies", tr("Vinyl Spinners Show/Hide (All Decks)"), tr("Show/Hide all spinnies"), - spinnyMenu); + pSpinnyMenu); // TODO(ronso0) Add hint that this currently only affects the Shade skin for (int i = 1; i <= iNumDecks; ++i) { addControl(QString("[Spinny%1]").arg(i), "show_spinny", QString("%1: %2").arg(m_deckStr.arg(i), spinnyTitle), QString("%1: %2").arg(m_deckStr.arg(i), spinnyDescription), - spinnyMenu); + pSpinnyMenu); } - guiMenu->addSeparator(); + pGuiMenu->addSeparator(); addControl("[Skin]", "show_waveforms", tr("Toggle Waveforms"), tr("Show/hide the scrolling waveforms."), - guiMenu); - addDeckControl("waveform_zoom", tr("Waveform Zoom"), tr("Waveform zoom"), guiMenu); - addDeckControl("waveform_zoom_down", tr("Waveform Zoom In"), tr("Zoom waveform in"), guiMenu); - addDeckControl("waveform_zoom_up", tr("Waveform Zoom Out"), tr("Zoom waveform out"), guiMenu); + pGuiMenu); + addDeckControl("waveform_zoom", tr("Waveform Zoom"), tr("Waveform zoom"), pGuiMenu); + addDeckControl("waveform_zoom_down", tr("Waveform Zoom In"), tr("Zoom waveform in"), pGuiMenu); + addDeckControl("waveform_zoom_up", tr("Waveform Zoom Out"), tr("Zoom waveform out"), pGuiMenu); addDeckControl("waveform_zoom_set_default", tr("Waveform Zoom Reset To Default"), tr("Reset the waveform zoom level to the default value selected in " "Preferences -> Waveforms"), - guiMenu); + pGuiMenu); - guiMenu->addSeparator(); + pGuiMenu->addSeparator(); // Controls to change a deck's star rating addDeckAndPreviewDeckControl("stars_up", tr("Star Rating Up"), tr("Increase the track rating by one star"), - guiMenu); + pGuiMenu); addDeckAndPreviewDeckControl("stars_down", tr("Star Rating Down"), tr("Decrease the track rating by one star"), - guiMenu); + pGuiMenu); // Misc. controls addControl("[Shoutcast]", "enabled", tr("Start/Stop Live Broadcasting"), tr("Stream your mix over the Internet."), - guiMenu); + pGuiMenu); addControl(RECORDING_PREF_KEY, "toggle_recording", tr("Record Mix"), tr("Start/stop recording your mix."), - guiMenu); + pGuiMenu); } ControlPickerMenu::~ControlPickerMenu() { @@ -1412,15 +1455,15 @@ void ControlPickerMenu::addPlayerControl(const QString& control, const int iNumPreviewDecks = static_cast( ControlObject::get(ConfigKey(kAppGroup, QStringLiteral("num_preview_decks")))); - parented_ptr controlMenu = make_parented(controlTitle, pMenu); - pMenu->addMenu(controlMenu); + parented_ptr pControlMenu = make_parented(controlTitle, pMenu); + pMenu->addMenu(pControlMenu); - parented_ptr resetControlMenu = nullptr; + parented_ptr pResetControlMenu = nullptr; QString resetControl = QString("%1_set_default").arg(control); if (addReset) { QString resetMenuTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); - resetControlMenu = make_parented(resetMenuTitle, pMenu); - pMenu->addMenu(resetControlMenu); + pResetControlMenu = make_parented(resetMenuTitle, pMenu); + pMenu->addMenu(pResetControlMenu); } for (int i = 1; deckControls && i <= iNumDecks; ++i) { @@ -1431,18 +1474,18 @@ void ControlPickerMenu::addPlayerControl(const QString& control, control, controlTitle, controlDescription, - controlMenu, + pControlMenu, prefix, prefix); - if (resetControlMenu) { + if (pResetControlMenu) { QString resetTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); QString resetDescription = QString("%1 (%2)").arg(controlDescription, m_resetStr); addSingleControl(group, resetControl, resetTitle, resetDescription, - resetControlMenu, + pResetControlMenu, prefix, prefix); } @@ -1461,32 +1504,41 @@ void ControlPickerMenu::addPlayerControl(const QString& control, control, controlTitle, controlDescription, - controlMenu, + pControlMenu, prefix, prefix); - if (resetControlMenu) { + if (pResetControlMenu) { QString resetTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); QString resetDescription = QString("%1 (%2)").arg(controlDescription, m_resetStr); addSingleControl(group, resetControl, resetTitle, resetDescription, - resetControlMenu, + pResetControlMenu, prefix, prefix); } } if (samplerControls) { - QMenu* samplerControlMenu = new QMenu(tr("Samplers"), controlMenu); - controlMenu->addMenu(samplerControlMenu); - QMenu* samplerResetControlMenu = nullptr; - if (resetControlMenu) { - samplerResetControlMenu = new QMenu(tr("Samplers"), resetControlMenu); - resetControlMenu->addMenu(samplerResetControlMenu); + QMenu* pSamplerControlMainMenu = addSubmenu(tr("Samplers"), pControlMenu); + QMenu* pSamplerControlMenu = pSamplerControlMainMenu; + QMenu* pSamplerResetControlMainMenu = nullptr; + QMenu* pSamplerResetControlMenu = nullptr; + if (pResetControlMenu) { + pSamplerResetControlMainMenu = addSubmenu(tr("Samplers"), pResetControlMenu); + pSamplerResetControlMenu = pSamplerResetControlMainMenu; } + const int maxSamplersPerMenu = 16; + int samplersInMenu = 0; + QString submenuLabel; for (int i = 1; i <= iNumSamplers; ++i) { + if (samplersInMenu == maxSamplersPerMenu) { + int limit = iNumSamplers > i + 15 ? i + 15 : iNumSamplers; + submenuLabel = m_samplerStr.arg(i) + QStringLiteral("- %1").arg(limit); + pSamplerControlMenu = addSubmenu(submenuLabel, pSamplerControlMainMenu); + } // PlayerManager::groupForSampler is 0-indexed. QString prefix = m_samplerStr.arg(i); QString group = PlayerManager::groupForSampler(i - 1); @@ -1494,21 +1546,29 @@ void ControlPickerMenu::addPlayerControl(const QString& control, control, controlTitle, controlDescription, - samplerControlMenu, + pSamplerControlMenu, prefix, prefix); - if (resetControlMenu) { + if (pResetControlMenu) { + if (samplersInMenu == maxSamplersPerMenu) { + pSamplerResetControlMenu = addSubmenu( + submenuLabel, pSamplerResetControlMainMenu); + } QString resetTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); QString resetDescription = QString("%1 (%2)").arg(controlDescription, m_resetStr); addSingleControl(group, resetControl, resetTitle, resetDescription, - samplerResetControlMenu, + pSamplerResetControlMenu, prefix, prefix); } + if (samplersInMenu == maxSamplersPerMenu) { + samplersInMenu = 0; + } + samplersInMenu++; } } } @@ -1520,15 +1580,15 @@ void ControlPickerMenu::addMicrophoneAndAuxControl(const QString& control, bool microphoneControls, bool auxControls, bool addReset) { - parented_ptr controlMenu = make_parented(controlTitle, pMenu); - pMenu->addMenu(controlMenu); + parented_ptr pControlMenu = make_parented(controlTitle, pMenu); + pMenu->addMenu(pControlMenu); - parented_ptr resetControlMenu = nullptr; + parented_ptr pResetControlMenu = nullptr; QString resetControl = QString("%1_set_default").arg(control); if (addReset) { QString resetHelpText = QString("%1 (%2)").arg(controlTitle, m_resetStr); - resetControlMenu = make_parented(resetHelpText, pMenu); - pMenu->addMenu(resetControlMenu); + pResetControlMenu = make_parented(resetHelpText, pMenu); + pMenu->addMenu(pResetControlMenu); } if (microphoneControls) { @@ -1541,18 +1601,18 @@ void ControlPickerMenu::addMicrophoneAndAuxControl(const QString& control, control, controlTitle, controlDescription, - controlMenu, + pControlMenu, prefix, prefix); - if (resetControlMenu) { + if (pResetControlMenu) { QString resetTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); QString resetDescription = QString("%1 (%2)").arg(controlDescription, m_resetStr); addSingleControl(group, resetControl, resetTitle, resetDescription, - resetControlMenu, + pResetControlMenu, prefix, prefix); } @@ -1569,18 +1629,18 @@ void ControlPickerMenu::addMicrophoneAndAuxControl(const QString& control, control, controlTitle, controlDescription, - controlMenu, + pControlMenu, prefix, prefix); - if (resetControlMenu) { + if (pResetControlMenu) { QString resetTitle = QString("%1 (%2)").arg(controlTitle, m_resetStr); QString resetDescription = QString("%1 (%2)").arg(controlDescription, m_resetStr); addSingleControl(group, resetControl, resetTitle, resetDescription, - resetControlMenu, + pResetControlMenu, prefix, prefix); } @@ -1647,9 +1707,9 @@ QMenu* ControlPickerMenu::addSubmenu(QString title, QMenu* pParent) { if (pParent == nullptr) { pParent = this; } - auto subMenu = make_parented(title, pParent); - pParent->addMenu(subMenu); - return subMenu; + auto pSubMenu = make_parented(title, pParent); + pParent->addMenu(pSubMenu); + return pSubMenu; } void ControlPickerMenu::controlChosen(int controlIndex) { diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp index 8d031b04066..22cdf2e165a 100644 --- a/src/controllers/dlgprefcontroller.cpp +++ b/src/controllers/dlgprefcontroller.cpp @@ -55,7 +55,7 @@ DlgPrefController::DlgPrefController( // Create text color for the file and wiki links createLinkColor(); - m_pControlPickerMenu = new ControlPickerMenu(this); + m_pControlPickerMenu = make_parented(this); initTableView(m_ui.m_pInputMappingTableView); initTableView(m_ui.m_pOutputMappingTableView); @@ -169,6 +169,10 @@ DlgPrefController::DlgPrefController( DlgPrefController::~DlgPrefController() { } +void DlgPrefController::slotRecreateControlPickerMenu() { + m_pControlPickerMenu = make_parented(this); +} + void DlgPrefController::showLearningWizard() { if (isDirty()) { QMessageBox::StandardButton result = QMessageBox::question(this, diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h index 0536c65e76f..eccd070f22b 100644 --- a/src/controllers/dlgprefcontroller.h +++ b/src/controllers/dlgprefcontroller.h @@ -7,17 +7,17 @@ #include "controllers/ui_dlgprefcontrollerdlg.h" #include "preferences/dialog/dlgpreferencepage.h" #include "preferences/usersettings.h" +#include "util/parented_ptr.h" // Forward declarations class Controller; -class ControllerManager; -class MappingInfoEnumerator; -class ControlPickerMenu; -class DlgControllerLearning; class ControllerInputMappingTableModel; class ControllerMappingTableProxyModel; +class ControllerManager; class ControllerOutputMappingTableModel; -class ControllerMappingTableProxyModel; +class ControlPickerMenu; +class DlgControllerLearning; +class MappingInfoEnumerator; /// Configuration dialog for a single DJ controller class DlgPrefController : public DlgPreferencePage { @@ -40,6 +40,8 @@ class DlgPrefController : public DlgPreferencePage { /// Called when the user clicks the global "Reset to Defaults" button. void slotResetToDefaults() override; + void slotRecreateControlPickerMenu(); + signals: void applyMapping(Controller* pController, std::shared_ptr pMapping, @@ -119,7 +121,7 @@ class DlgPrefController : public DlgPreferencePage { const QString m_pUserDir; std::shared_ptr m_pControllerManager; Controller* m_pController; - ControlPickerMenu* m_pControlPickerMenu; + parented_ptr m_pControlPickerMenu; DlgControllerLearning* m_pDlgControllerLearning; std::shared_ptr m_pMapping; QMap m_pOverwriteMappings; diff --git a/src/controllers/dlgprefcontrollers.cpp b/src/controllers/dlgprefcontrollers.cpp index 69e18291a68..43b349d07f5 100644 --- a/src/controllers/dlgprefcontrollers.cpp +++ b/src/controllers/dlgprefcontrollers.cpp @@ -2,6 +2,7 @@ #include +#include "control/controlproxy.h" #include "controllers/controller.h" #include "controllers/controllermanager.h" #include "controllers/defs_controllers.h" @@ -11,6 +12,10 @@ #include "preferences/dialog/dlgpreferences.h" #include "util/string.h" +namespace { +const QString kAppGroup = QStringLiteral("[App]"); +} // namespace + DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences, UserSettingsPointer pConfig, std::shared_ptr pControllerManager, @@ -19,7 +24,11 @@ DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences, m_pDlgPreferences(pPreferences), m_pConfig(pConfig), m_pControllerManager(pControllerManager), - m_pControllersRootItem(pControllersRootItem) { + m_pControllersRootItem(pControllersRootItem), + m_pNumDecks(make_parented( + kAppGroup, QStringLiteral("num_decks"), this)), + m_pNumSamplers(make_parented( + kAppGroup, QStringLiteral("num_samplers"), this)) { setupUi(this); // Create text color for the cue mode link "?" to the manual createLinkColor(); @@ -178,6 +187,11 @@ void DlgPrefControllers::setupControllerWidgets() { &DlgPrefController::mappingEnded, m_pDlgPreferences, &DlgPreferences::show); + // Recreate the control picker menus when decks or samplers are added + m_pNumDecks->connectValueChanged(pControllerDlg, + &DlgPrefController::slotRecreateControlPickerMenu); + m_pNumSamplers->connectValueChanged(pControllerDlg, + &DlgPrefController::slotRecreateControlPickerMenu); m_controllerPages.append(pControllerDlg); diff --git a/src/controllers/dlgprefcontrollers.h b/src/controllers/dlgprefcontrollers.h index d9cca0ebaed..06e334f0905 100644 --- a/src/controllers/dlgprefcontrollers.h +++ b/src/controllers/dlgprefcontrollers.h @@ -5,7 +5,9 @@ #include "controllers/ui_dlgprefcontrollersdlg.h" #include "preferences/dialog/dlgpreferencepage.h" #include "preferences/usersettings.h" +#include "util/parented_ptr.h" +class ControlProxy; class DlgPreferences; class DlgPrefController; class ControllerManager; @@ -52,4 +54,7 @@ class DlgPrefControllers : public DlgPreferencePage, public Ui::DlgPrefControlle QTreeWidgetItem* m_pControllersRootItem; QList m_controllerPages; QList m_controllerTreeItems; + + const parented_ptr m_pNumDecks; + const parented_ptr m_pNumSamplers; }; diff --git a/src/mixer/playermanager.cpp b/src/mixer/playermanager.cpp index a70dc1f32d5..08cbbdf66b8 100644 --- a/src/mixer/playermanager.cpp +++ b/src/mixer/playermanager.cpp @@ -450,7 +450,12 @@ void PlayerManager::addDeckInner() { } void PlayerManager::loadSamplers() { - m_pSamplerBank->loadSamplerBankFromPath(getDefaultSamplerPath(m_pConfig)); + // This is only called by CoreServices during startup to restore + // samplers from the previous session. + // We don't want it to create more players than necessary. + bool dontCreateEmptySamplers = true; + m_pSamplerBank->loadSamplerBankFromPath(getDefaultSamplerPath(m_pConfig), + dontCreateEmptySamplers); } void PlayerManager::addSampler() { diff --git a/src/mixer/samplerbank.cpp b/src/mixer/samplerbank.cpp index 267ad218321..647cc269634 100644 --- a/src/mixer/samplerbank.cpp +++ b/src/mixer/samplerbank.cpp @@ -165,7 +165,8 @@ void SamplerBank::slotLoadSamplerBank(double v) { } } -bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath) { +bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath, + bool dontCreateEmptySamplers) { // The user has picked a new directory via a file dialog. This means the // system sandboxer (if we are sandboxed) has granted us permission to this // folder. We don't need access to this file on a regular basis so we do not @@ -195,33 +196,47 @@ bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath) { return false; } - QDomNode n = root.firstChild(); - - while (!n.isNull()) { + const auto samplerNodes = root.childNodes(); + if (samplerNodes.isEmpty()) { + return true; + } + for (int i = 0; i < samplerNodes.size(); i++) { + QDomNode n = samplerNodes.at(i); QDomElement e = n.toElement(); + if (e.isNull() || e.tagName() != "sampler") { + continue; + } + + const QString group = e.attribute("group", ""); + const QString location = e.attribute("location", ""); + int samplerNum; + + if (group.isEmpty() || !m_pPlayerManager->isSamplerGroup(group, &samplerNum)) { + continue; + } + + // During startup we only increase the sampler count if there is + // a track to be loaded. This avoids + // * creating more sampler players than strictly necessary + // * an unnecessary large Load To > Sampler N submenu in the track menu + if (dontCreateEmptySamplers && location.isEmpty()) { + continue; + } + + // Later on, when the user loads a samplers file manually, we + // want to eject loaded tracks if the file's sample slot is empty. + // We also create new players even if they are not present in the + // GUI to not drop tracks loaded to invisible samplers when saving + // the samplers file. + if (static_cast(m_pPlayerManager->numSamplers()) < samplerNum) { + m_pCONumSamplers->set(samplerNum); + } - if (!e.isNull()) { - if (e.tagName() == "sampler") { - QString group = e.attribute("group", ""); - QString location = e.attribute("location", ""); - int samplerNum; - - if (!group.isEmpty() - && m_pPlayerManager->isSamplerGroup(group, &samplerNum)) { - if (m_pPlayerManager->numSamplers() < (unsigned) samplerNum) { - m_pCONumSamplers->set(samplerNum); - } - - if (location.isEmpty()) { - m_pPlayerManager->slotLoadTrackToPlayer(TrackPointer(), group, false); - } else { - m_pPlayerManager->slotLoadLocationToPlayer(location, group, false); - } - } - - } + if (location.isEmpty()) { + m_pPlayerManager->slotLoadTrackToPlayer(TrackPointer(), group, false); + } else { + m_pPlayerManager->slotLoadLocationToPlayer(location, group, false); } - n = n.nextSibling(); } file.close(); diff --git a/src/mixer/samplerbank.h b/src/mixer/samplerbank.h index 5234f045f71..0f787e089d2 100644 --- a/src/mixer/samplerbank.h +++ b/src/mixer/samplerbank.h @@ -19,7 +19,8 @@ class SamplerBank : public QObject { PlayerManager* pPlayerManager); bool saveSamplerBankToPath(const QString& samplerBankPath); - bool loadSamplerBankFromPath(const QString& samplerBankPath); + bool loadSamplerBankFromPath(const QString& samplerBankPath, + bool dontCreateEmptySamplers = false); private slots: void slotSaveSamplerBank(double v); diff --git a/src/widget/wtrackmenu.cpp b/src/widget/wtrackmenu.cpp index 0b51f595ad4..e2cd149f2c2 100644 --- a/src/widget/wtrackmenu.cpp +++ b/src/widget/wtrackmenu.cpp @@ -12,7 +12,6 @@ #include "analyzer/analyzersilence.h" #include "analyzer/analyzertrack.h" #include "control/controlobject.h" -#include "control/controlproxy.h" #include "library/coverartutils.h" #include "library/dao/trackschema.h" #include "library/dlgtagfetcher.h" @@ -49,6 +48,11 @@ namespace { const QString kAppGroup = QStringLiteral("[App]"); + +const QString samplerTrString(int i) { + return QObject::tr("Sampler %1").arg(i); +} + } // namespace WTrackMenu::WTrackMenu( @@ -61,14 +65,13 @@ WTrackMenu::WTrackMenu( m_pTrackModel(trackModel), m_pConfig(pConfig), m_pLibrary(pLibrary), + m_pNumSamplers(kAppGroup, QStringLiteral("num_samplers")), + m_pNumDecks(kAppGroup, QStringLiteral("num_decks")), + m_pNumPreviewDecks(kAppGroup, QStringLiteral("num_preview_decks")), m_bPlaylistMenuLoaded(false), m_bCrateMenuLoaded(false), m_eActiveFeatures(flags), m_eTrackModelFeatures(Feature::TrackModelFeatures) { - m_pNumSamplers = new ControlProxy(kAppGroup, QStringLiteral("num_samplers"), this); - m_pNumDecks = new ControlProxy(kAppGroup, QStringLiteral("num_decks"), this); - m_pNumPreviewDecks = new ControlProxy(kAppGroup, QStringLiteral("num_preview_decks"), this); - // Warn if any of the chosen features depend on a TrackModel VERIFY_OR_DEBUG_ASSERT(trackModel || (m_eTrackModelFeatures & flags) == 0) { // Remove unsupported features @@ -507,7 +510,7 @@ void WTrackMenu::setupActions() { m_pLoadToMenu->addMenu(m_pSamplerMenu); - if (m_pNumPreviewDecks->get() > 0.0) { + if (m_pNumPreviewDecks.get() > 0.0) { m_pLoadToMenu->addAction(m_pAddToPreviewDeck); } @@ -783,7 +786,7 @@ void WTrackMenu::updateMenus() { const bool singleTrackSelected = getTrackCount() == 1; if (featureIsEnabled(Feature::LoadTo)) { - int iNumDecks = static_cast(m_pNumDecks->get()); + int iNumDecks = static_cast(m_pNumDecks.get()); m_pDeckMenu->clear(); if (iNumDecks > 0) { for (int i = 1; i <= iNumDecks; ++i) { @@ -818,19 +821,35 @@ void WTrackMenu::updateMenus() { } } - int iNumSamplers = static_cast(m_pNumSamplers->get()); + int iNumSamplers = static_cast(m_pNumSamplers.get()); + const int maxSamplersPerMenu = 16; if (iNumSamplers > 0) { m_pSamplerMenu->clear(); + QMenu* pMenu = m_pSamplerMenu; + int samplersInMenu = 0; for (int i = 1; i <= iNumSamplers; ++i) { + if (samplersInMenu == maxSamplersPerMenu) { + samplersInMenu = 0; + int limit = iNumSamplers > i + 15 ? i + 15 : iNumSamplers; + const QString label = samplerTrString(i) + QStringLiteral("- %1").arg(limit); + pMenu = new QMenu(label, m_pSamplerMenu); + m_pSamplerMenu->addMenu(pMenu); + } + samplersInMenu++; // PlayerManager::groupForSampler is 0-indexed. QString samplerGroup = PlayerManager::groupForSampler(i - 1); bool samplerPlaying = ControlObject::get( ConfigKey(samplerGroup, "play")) > 0.0; bool samplerEnabled = !samplerPlaying && singleTrackSelected; - QAction* pAction = new QAction(tr("Sampler %1").arg(i), m_pSamplerMenu); + QAction* pAction = new QAction(samplerTrString(i), pMenu); pAction->setEnabled(samplerEnabled); - m_pSamplerMenu->addAction(pAction); - connect(pAction, &QAction::triggered, this, [this, samplerGroup] { loadSelectionToGroup(samplerGroup); }); + pMenu->addAction(pAction); + connect(pAction, + &QAction::triggered, + this, + [this, samplerGroup] { + loadSelectionToGroup(samplerGroup); + }); } } } diff --git a/src/widget/wtrackmenu.h b/src/widget/wtrackmenu.h index c7ecc79f5f5..d3208a56dd0 100644 --- a/src/widget/wtrackmenu.h +++ b/src/widget/wtrackmenu.h @@ -6,6 +6,7 @@ #include #include "analyzer/analyzertrack.h" +#include "control/pollingcontrolproxy.h" #include "library/coverart.h" #include "library/dao/playlistdao.h" #include "library/trackprocessing.h" @@ -15,7 +16,6 @@ #include "util/color/rgbcolor.h" #include "util/parented_ptr.h" -class ControlProxy; class DlgTagFetcher; class DlgTrackInfo; //class DlgDeleteFilesConfirmation; @@ -218,10 +218,6 @@ class WTrackMenu : public QMenu { /// deck made the request. QString m_deckGroup; - const ControlProxy* m_pNumSamplers{}; - const ControlProxy* m_pNumDecks{}; - const ControlProxy* m_pNumPreviewDecks{}; - // Submenus QMenu* m_pLoadToMenu{}; QMenu* m_pDeckMenu{}; @@ -315,6 +311,10 @@ class WTrackMenu : public QMenu { const UserSettingsPointer m_pConfig; Library* const m_pLibrary; + PollingControlProxy m_pNumSamplers; + PollingControlProxy m_pNumDecks; + PollingControlProxy m_pNumPreviewDecks; + std::unique_ptr m_pDlgTrackInfo; std::unique_ptr m_pDlgTagFetcher;