1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-04 22:29:27 +02:00
audacity/src/tracks/playabletrack/notetrack/ui/NoteTrackControls.cpp
2017-07-10 23:18:33 -04:00

140 lines
3.6 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
NoteTrackControls.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "../../../../Audacity.h"
#ifdef USE_MIDI
#include "NoteTrackControls.h"
#include "NoteTrackButtonHandle.h"
#include "../../ui/PlayableTrackButtonHandles.h"
#include "NoteTrackSliderHandles.h"
#include "../../../../HitTestResult.h"
#include "../../../../TrackPanelMouseEvent.h"
#include "../../../../NoteTrack.h"
#include "../../../../widgets/PopupMenuTable.h"
#include "../../../../Project.h"
#include "../../../../RefreshCode.h"
///////////////////////////////////////////////////////////////////////////////
NoteTrackControls::~NoteTrackControls()
{
}
std::vector<UIHandlePtr> NoteTrackControls::HitTest
(const TrackPanelMouseState & st,
const AudacityProject *pProject)
{
// Hits are mutually exclusive, results single
std::vector<UIHandlePtr> results;
const wxMouseState &state = st.state;
const wxRect &rect = st.rect;
if (state.ButtonIsDown(wxMOUSE_BTN_ANY)) {
auto track = std::static_pointer_cast<NoteTrack>(FindTrack());
auto result = [&]{
UIHandlePtr result;
if (NULL != (result = MuteButtonHandle::HitTest(
mMuteHandle, state, rect, pProject, track)))
return result;
if (NULL != (result = SoloButtonHandle::HitTest(
mSoloHandle, state, rect, pProject, track)))
return result;
#ifdef EXPERIMENTAL_MIDI_OUT
if (NULL != (result = VelocitySliderHandle::HitTest(
mVelocityHandle, state, rect, track)))
return result;
if (NULL != (result = NoteTrackButtonHandle::HitTest(
mClickHandle, state, rect, track)))
return result;
#endif
return result;
}();
if (result) {
results.push_back(result);
return results;
}
}
return TrackControls::HitTest(st, pProject);
}
class NoteTrackMenuTable : public PopupMenuTable
{
NoteTrackMenuTable() : mpData(NULL) {}
DECLARE_POPUP_MENU(NoteTrackMenuTable);
public:
static NoteTrackMenuTable &Instance();
private:
void InitMenu(Menu*, void *pUserData) override
{
mpData = static_cast<TrackControls::InitMenuData*>(pUserData);
}
void DestroyMenu() override
{
mpData = nullptr;
}
TrackControls::InitMenuData *mpData;
void OnChangeOctave(wxCommandEvent &);
};
NoteTrackMenuTable &NoteTrackMenuTable::Instance()
{
static NoteTrackMenuTable instance;
return instance;
}
enum {
OnUpOctaveID = 30000,
OnDownOctaveID,
};
/// This only applies to MIDI tracks. Presumably, it shifts the
/// whole sequence by an octave.
void NoteTrackMenuTable::OnChangeOctave(wxCommandEvent &event)
{
NoteTrack *const pTrack = static_cast<NoteTrack*>(mpData->pTrack);
wxASSERT(event.GetId() == OnUpOctaveID
|| event.GetId() == OnDownOctaveID);
wxASSERT(pTrack->GetKind() == Track::Note);
const bool bDown = (OnDownOctaveID == event.GetId());
pTrack->SetBottomNote
(pTrack->GetBottomNote() + ((bDown) ? -12 : 12));
AudacityProject *const project = ::GetActiveProject();
project->ModifyState(true);
mpData->result = RefreshCode::RefreshAll;
}
BEGIN_POPUP_MENU(NoteTrackMenuTable)
POPUP_MENU_SEPARATOR()
POPUP_MENU_ITEM(OnUpOctaveID, _("Up &Octave"), OnChangeOctave)
POPUP_MENU_ITEM(OnDownOctaveID, _("Down Octa&ve"), OnChangeOctave)
END_POPUP_MENU()
PopupMenuTable *NoteTrackControls::GetMenuExtension(Track *)
{
#if defined(USE_MIDI)
return &NoteTrackMenuTable::Instance();
#else
return NULL;
#endif
}
#endif