Audacity 3.2.0
NoteTrackButtonHandle.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5NoteTrackButtonHandle.cpp
6
7Paul Licameli split from TrackPanel.cpp
8
9**********************************************************************/
10
11
12
13#ifdef USE_MIDI
15
16#include "../../../../HitTestResult.h"
17#include "NoteTrackControls.h"
18#include "../../../../TrackPanelMouseEvent.h"
19#include "NoteTrack.h"
20#include "ProjectHistory.h"
21#include "../../../../RefreshCode.h"
22#include "../../../ui/CommonTrackInfo.h"
23
24#include <wx/event.h>
25
27( const std::shared_ptr<NoteTrack> &pTrack,
28 int channel, const wxRect &rect )
29 : mpTrack{ pTrack }
30 , mChannel{ channel }
31 , mRect{ rect }
32{
33}
34
36{
38}
39
41{
42}
43
44std::shared_ptr<const Track> NoteTrackButtonHandle::FindTrack() const
45{
46 return mpTrack.lock();
47}
48
50(const NoteTrackButtonHandle &oldState, const NoteTrackButtonHandle &newState)
51{
52 if (oldState.GetChannel() != newState.GetChannel())
53 // Repaint whenever the highlighted button is different
55 return 0;
56}
57
58static int FindChannelNumber(const wxRect &rect, int mx, int my)
59{
60 wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4");
61 wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4");
62
63 auto cellWidth = rect.width / 4;
64 auto cellHeight = rect.height / 4;
65
66 int col = (mx - rect.x) / cellWidth;
67 int row = (my - rect.y) / cellHeight;
68
69 return row * 4 + col;
70}
71
72
73// Handles clicking within the midi controls rect (same as DrawLabelControls).
74// This is somewhat oddly written, as these aren't real buttons - they act
75// when the mouse goes down; you can't hold it pressed and move off of it.
76// Left-clicking toggles a single channel; right-clicking turns off all other channels.
77static bool LabelClick(
78 NoteTrack &track, const wxRect &rect, int mx, int my, bool right)
79{
80 auto channel = FindChannelNumber(rect, mx, my);
81 if (right)
82 track.SoloVisibleChan(channel);
83 else
84 track.ToggleVisibleChan(channel);
85
86 return true;
87}
88
90 (std::weak_ptr<NoteTrackButtonHandle> &holder,
91 const wxMouseState &state, const wxRect &rect,
92 const std::shared_ptr<NoteTrack> &pTrack)
93{
94 wxRect midiRect;
96 if ( CommonTrackInfo::HideTopItem( rect, midiRect ) )
97 return {};
98 if (midiRect.Contains(state.m_x, state.m_y)) {
99 auto channel = FindChannelNumber(midiRect, state.m_x, state.m_y);
100 auto result = std::make_shared<NoteTrackButtonHandle>(
101 pTrack, channel, midiRect );
102 result = AssignUIHandlePtr(holder, result);
103 return result;
104 }
105 else
106 return {};
107}
108
111{
113}
114
117{
119}
120
123{
124 // auto pTrack = pProject->GetTracks()->Lock(mpTrack);
125 auto pTrack = mpTrack.lock();
126 if ( !pTrack )
127 return {};
128 // No special message or cursor
129 return {};
130}
131
133(const TrackPanelMouseEvent &evt, AudacityProject *pProject, wxWindow *)
134{
135 using namespace RefreshCode;
136
137 auto pTrack = TrackList::Get( *pProject ).Lock(mpTrack);
138 if (!pTrack)
139 return Cancelled;
140
141 const wxMouseEvent &event = evt.event;
142 if (LabelClick(*pTrack, mRect, event.m_x, event.m_y,
143 event.Button(wxMOUSE_BTN_RIGHT))) {
144 // No undo items needed??
145 ProjectHistory::Get( *pProject ).ModifyState(false);
146 return RefreshAll;
147 }
148 return RefreshNone;
149}
150
152{
154}
155
156#endif
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
static bool LabelClick(NoteTrack &track, const wxRect &rect, int mx, int my, bool right)
static int FindChannelNumber(const wxRect &rect, int mx, int my)
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:164
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static UIHandle::Result NeedChangeHighlight(const NoteTrackButtonHandle &oldState, const NoteTrackButtonHandle &newState)
std::shared_ptr< const Track > FindTrack() const override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
void Enter(bool forward, AudacityProject *) override
std::weak_ptr< NoteTrack > mpTrack
Result Cancel(AudacityProject *pProject) override
static UIHandlePtr HitTest(std::weak_ptr< NoteTrackButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< NoteTrack > &pTrack)
static void GetMidiControlsRect(const wxRect &rect, wxRect &dest)
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:78
void ToggleVisibleChan(int c)
Definition: NoteTrack.h:163
void SoloVisibleChan(int c)
Definition: NoteTrack.h:167
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:1079
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
Result mChangeHighlight
Definition: UIHandle.h:152
unsigned Result
Definition: UIHandle.h:40
AUDACITY_DLL_API bool HideTopItem(const wxRect &rect, const wxRect &subRect, int allowance=0)
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16