1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 17:09:26 +02:00

MIDI play changes for TrackPanel, MixerBoard; conditionally compiled

This commit is contained in:
Paul Licameli 2017-04-01 12:49:20 -04:00
commit 08e57f3836
7 changed files with 272 additions and 156 deletions

View File

@ -728,7 +728,7 @@ void AudacityProject::CreateMenusAndCommands()
AudioIONotBusyFlag);
c->AddItem(wxT("Karaoke"), _("&Karaoke..."), FN(OnKaraoke), LabelTracksExistFlag, LabelTracksExistFlag);
c->AddItem(wxT("MixerBoard"), _("&Mixer Board..."), FN(OnMixerBoard), WaveTracksExistFlag, WaveTracksExistFlag);
c->AddItem(wxT("MixerBoard"), _("&Mixer Board..."), FN(OnMixerBoard), PlayableTracksExistFlag, PlayableTracksExistFlag);
c->AddSeparator();
@ -1836,6 +1836,7 @@ CommandFlag AudacityProject::GetUpdateFlags(bool checkActive)
}
else if (t->GetKind() == Track::Wave) {
flags |= WaveTracksExistFlag;
flags |= PlayableTracksExistFlag;
if (t->GetSelected()) {
flags |= TracksSelectedFlag;
if (t->GetLinked()) {
@ -1853,6 +1854,9 @@ CommandFlag AudacityProject::GetUpdateFlags(bool checkActive)
NoteTrack *nt = (NoteTrack *) t;
flags |= NoteTracksExistFlag;
#ifdef EXPERIMENTAL_MIDI_OUT
flags |= PlayableTracksExistFlag;
#endif
if (nt->GetSelected()) {
flags |= TracksSelectedFlag;

View File

@ -24,7 +24,9 @@
#include "AColor.h"
#include "AudioIO.h"
#ifdef USE_MIDI
#include "NoteTrack.h"
#endif
#include "Project.h"
#include "TrackPanel.h" // for EVT_TRACK_PANEL_TIMER
@ -137,6 +139,9 @@ enum {
ID_BITMAPBUTTON_MUSICAL_INSTRUMENT = 13000,
ID_SLIDER_PAN,
ID_SLIDER_GAIN,
#ifdef EXPERIMENTAL_MIDI_OUT
ID_SLIDER_VELOCITY,
#endif
ID_TOGGLEBUTTON_MUTE,
ID_TOGGLEBUTTON_SOLO,
};
@ -148,6 +153,9 @@ BEGIN_EVENT_TABLE(MixerTrackCluster, wxPanelWrapper)
EVT_BUTTON(ID_BITMAPBUTTON_MUSICAL_INSTRUMENT, MixerTrackCluster::OnButton_MusicalInstrument)
EVT_SLIDER(ID_SLIDER_PAN, MixerTrackCluster::OnSlider_Pan)
EVT_SLIDER(ID_SLIDER_GAIN, MixerTrackCluster::OnSlider_Gain)
#ifdef EXPERIMENTAL_MIDI_OUT
EVT_SLIDER(ID_SLIDER_VELOCITY, MixerTrackCluster::OnSlider_Velocity)
#endif
//v EVT_COMMAND_SCROLL(ID_SLIDER_GAIN, MixerTrackCluster::OnSliderScroll_Gain)
EVT_COMMAND(ID_TOGGLEBUTTON_MUTE, wxEVT_COMMAND_BUTTON_CLICKED, MixerTrackCluster::OnButton_Mute)
EVT_COMMAND(ID_TOGGLEBUTTON_SOLO, wxEVT_COMMAND_BUTTON_CLICKED, MixerTrackCluster::OnButton_Solo)
@ -184,25 +192,13 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
// mStaticText_TrackName->SetBackgroundColour(this->GetTrackColor());
// gain slider at left
// gain and velocity sliders at left (both in same place)
ctrlPos.x = kDoubleInset;
ctrlPos.y += TRACK_NAME_HEIGHT + kDoubleInset;
const int nGainSliderHeight =
size.GetHeight() - ctrlPos.y - kQuadrupleInset;
ctrlSize.Set(kLeftSideStackWidth - kQuadrupleInset, nGainSliderHeight);
#ifdef USE_MIDI
if (GetNote()) {
mSlider_Gain =
safenew MixerTrackSlider(
this, ID_SLIDER_GAIN,
/* i18n-hint: title of the MIDI Velocity slider */
_("Velocity"),
ctrlPos, ctrlSize, VEL_SLIDER, true,
true, 0.0, wxVERTICAL);
}
else
#endif
mSlider_Gain =
safenew MixerTrackSlider(
this, ID_SLIDER_GAIN,
@ -210,11 +206,19 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent,
_("Gain"),
ctrlPos, ctrlSize, DB_SLIDER, true,
true, 0.0, wxVERTICAL);
mSlider_Gain->SetName(_("Gain"));
this->UpdateGain();
#ifdef EXPERIMENTAL_MIDI_OUT
mSlider_Velocity =
safenew MixerTrackSlider(
this, ID_SLIDER_VELOCITY,
/* i18n-hint: title of the MIDI Velocity slider */
_("Velocity"),
ctrlPos, ctrlSize, VEL_SLIDER, true,
true, 0.0, wxVERTICAL);
mSlider_Velocity->SetName(_("Velocity"));
this->UpdateVelocity();
#endif
// other controls and meter at right
@ -329,7 +333,7 @@ WaveTrack *MixerTrackCluster::GetRight() const
return nullptr;
}
#ifdef USE_MIDI
#ifdef EXPERIMENTAL_MIDI_OUT
NoteTrack *MixerTrackCluster::GetNote() const
{
return dynamic_cast< NoteTrack * >( mTrack );
@ -361,6 +365,9 @@ void MixerTrackCluster::HandleResize() // For wxSizeEvents, update gain slider a
TRACK_NAME_HEIGHT + kDoubleInset) - // mStaticText_TrackName + margin
kQuadrupleInset; // margin below gain slider
mSlider_Gain->SetSize(-1, nGainSliderHeight);
#ifdef EXPERIMENTAL_MIDI_OUT
mSlider_Velocity->SetSize(-1, nGainSliderHeight);
#endif
bool bSoloNone = mProject->IsSoloNone();
@ -384,10 +391,6 @@ void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
float fValue = mSlider_Gain->Get();
if (GetWave())
GetWave()->SetGain(fValue);
#ifdef EXPERIMENTAL_MIDI_OUT
else
GetNote()->SetVelocity(fValue);
#endif
if (GetRight())
GetRight()->SetGain(fValue);
@ -397,6 +400,20 @@ void MixerTrackCluster::HandleSliderGain(const bool bWantPushState /*= false*/)
mProject->TP_PushState(_("Moved gain slider"), _("Gain"), UndoPush::CONSOLIDATE );
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerTrackCluster::HandleSliderVelocity(const bool bWantPushState /*= false*/)
{
float fValue = mSlider_Velocity->Get();
if (GetNote())
GetNote()->SetVelocity(fValue);
// Update the TrackPanel correspondingly.
mProject->RefreshTPTrack(mTrack);
if (bWantPushState)
mProject->TP_PushState(_("Moved velocity slider"), _("Velocity"), UndoPush::CONSOLIDATE);
}
#endif
void MixerTrackCluster::HandleSliderPan(const bool bWantPushState /*= false*/)
{
float fValue = mSlider_Pan->Get();
@ -462,28 +479,33 @@ void MixerTrackCluster::UpdateSolo()
void MixerTrackCluster::UpdatePan()
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (!GetWave()) {
mSlider_Pan->Hide();
return;
}
#endif
mSlider_Pan->Set(GetWave()->GetPan());
}
void MixerTrackCluster::UpdateGain()
{
#ifdef EXPERIMENTAL_MIDI_OUT
if (!GetWave()) {
mSlider_Gain->SetStyle(VEL_SLIDER);
mSlider_Gain->Set(GetNote()->GetVelocity());
mSlider_Gain->Hide();
return;
}
mSlider_Gain->SetStyle(DB_SLIDER);
#endif
mSlider_Gain->Set(GetWave()->GetGain());
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerTrackCluster::UpdateVelocity()
{
if (!GetNote()) {
mSlider_Velocity->Hide();
return;
}
mSlider_Velocity->Set(GetNote()->GetVelocity());
}
#endif
void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
{
// NoteTracks do not (currently) register on meters. It would probably be
@ -696,6 +718,13 @@ void MixerTrackCluster::OnSlider_Gain(wxCommandEvent& WXUNUSED(event))
this->HandleSliderGain();
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerTrackCluster::OnSlider_Velocity(wxCommandEvent& WXUNUSED(event))
{
this->HandleSliderVelocity();
}
#endif
//v void MixerTrackCluster::OnSliderScroll_Gain(wxScrollEvent& WXUNUSED(event))
//{
//int sliderValue = (int)(mSlider_Gain->Get()); //v mSlider_Gain->GetValue();
@ -1209,6 +1238,16 @@ void MixerBoard::UpdateGain(const PlayableTrack* pTrack)
pMixerTrackCluster->UpdateGain();
}
#ifdef EXPERIMENTAL_MIDI_OUT
void MixerBoard::UpdateVelocity(const PlayableTrack* pTrack)
{
MixerTrackCluster* pMixerTrackCluster;
FindMixerTrackCluster(pTrack, &pMixerTrackCluster);
if (pMixerTrackCluster)
pMixerTrackCluster->UpdateVelocity();
}
#endif
void MixerBoard::UpdateMeters(const double t1, const bool bLoopedPlay)
{
if (!this->IsShown() || (t1 == BAD_STREAM_TIME))

View File

@ -64,7 +64,9 @@ class Meter;
class MixerBoard;
class Track;
#ifdef USE_MIDI
class NoteTrack;
#endif
class PlayableTrack;
class WaveTrack;
@ -81,13 +83,18 @@ public:
WaveTrack *GetWave() const;
WaveTrack *GetRight() const;
#ifdef EXPERIMENTAL_MIDI_OUT
NoteTrack *GetNote() const;
#endif
void UpdatePrefs();
void HandleResize(); // For wxSizeEvents, update gain slider and meter.
void HandleSliderGain(const bool bWantPushState = false);
#ifdef EXPERIMENTAL_MIDI_OUT
void HandleSliderVelocity(const bool bWantPushState = false);
#endif
void HandleSliderPan(const bool bWantPushState = false);
void ResetMeter(const bool bResetClipping);
@ -99,6 +106,9 @@ public:
void UpdateSolo();
void UpdatePan();
void UpdateGain();
#ifdef EXPERIMENTAL_MIDI_OUT
void UpdateVelocity();
#endif
void UpdateMeter(const double t0, const double t1);
private:
@ -113,6 +123,9 @@ private:
void OnButton_MusicalInstrument(wxCommandEvent& event);
void OnSlider_Gain(wxCommandEvent& event);
#ifdef EXPERIMENTAL_MIDI_OUT
void OnSlider_Velocity(wxCommandEvent& event);
#endif
void OnSlider_Pan(wxCommandEvent& event);
void OnButton_Mute(wxCommandEvent& event);
void OnButton_Solo(wxCommandEvent& event);
@ -133,6 +146,9 @@ private:
AButton* mToggleButton_Solo;
MixerTrackSlider* mSlider_Pan;
MixerTrackSlider* mSlider_Gain;
#ifdef EXPERIMENTAL_MIDI_OUT
MixerTrackSlider* mSlider_Velocity;
#endif
Meter* mMeter;
public:
@ -222,6 +238,9 @@ public:
void UpdateSolo(const PlayableTrack* pTrack = NULL); // NULL means update for all tracks.
void UpdatePan(const PlayableTrack* pTrack);
void UpdateGain(const PlayableTrack* pTrack);
#ifdef EXPERIMENTAL_MIDI_OUT
void UpdateVelocity(const PlayableTrack* pTrack);
#endif
void UpdateMeters(const double t1, const bool bLoopedPlay);

View File

@ -177,11 +177,6 @@ class AUDACITY_DLL_API NoteTrack final
void StartVScroll();
void VScroll(int start, int end);
#ifdef EXPERIMENTAL_MIDI_OUT
wxRect GetGainPlacementRect() const { return mGainPlacementRect; }
void SetGainPlacementRect(const wxRect &r) { mGainPlacementRect = r; }
#endif
bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) override;
XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
void WriteXML(XMLWriter &xmlFile) const override;
@ -224,7 +219,6 @@ class AUDACITY_DLL_API NoteTrack final
int mPitchHeight;
int mVisibleChannels; // bit set of visible channels
int mLastMidiPosition;
wxRect mGainPlacementRect;
};
#endif // USE_MIDI

View File

@ -1182,7 +1182,8 @@ void TrackPanel::HandleInterruptedDrag()
IsGainSliding,
IsPanSliding,
WasOverCutLine,
IsStretching
IsStretching,
IsVelocitySliding
*/
// The bogus id isn't used anywhere, but may help with debugging.
// as this is sending a bogus mouse up. The mouse button is still actually down
@ -4841,7 +4842,7 @@ void TrackPanel::HandleMutingSoloing(wxMouseEvent & event, bool solo)
}
wxRect buttonRect;
mTrackInfo.GetMuteSoloRect(rect, buttonRect, solo, HasSoloButton());
mTrackInfo.GetMuteSoloRect(rect, buttonRect, solo, HasSoloButton(), t);
wxClientDC dc(this);
@ -4906,6 +4907,7 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
bool panZero = false;
#endif
wxASSERT(mCapturedTrack->GetKind() == Track::Wave);
// On the Mac, we'll lose track capture if the slider dialog
// is displayed, but it doesn't hurt to do this for all plats.
@ -4924,20 +4926,15 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
float newValue = slider->Get();
MixerBoard* pMixerBoard = this->GetMixerBoard(); // Update mixer board, too.
#ifdef EXPERIMENTAL_MIDI_OUT
if (capturedTrack->GetKind() == Track::Wave)
#endif
{
const auto wt = static_cast<WaveTrack*>(capturedTrack);
// Assume linked track is wave or null
const auto link = static_cast<WaveTrack *>(wt->GetLink());
const auto link = static_cast<WaveTrack *>(capturedTrack->GetLink());
if (pan) {
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
panZero = wt->SetPan(newValue);
panZero = capturedTrack->SetPan(newValue);
#else
wt->SetPan(newValue);
capturedTrack->SetPan(newValue);
#endif
if (link)
link->SetPan(newValue);
@ -4947,51 +4944,57 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
#endif
if (pMixerBoard)
pMixerBoard->UpdatePan(wt);
pMixerBoard->UpdatePan(capturedTrack);
}
else {
wt->SetGain(newValue);
capturedTrack->SetGain(newValue);
if (link)
link->SetGain(newValue);
if (pMixerBoard)
pMixerBoard->UpdateGain(wt);
pMixerBoard->UpdateGain(capturedTrack);
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
else {
// mCapturedTrack is not wave...
if (!pan) {
// .. so assume it is note
static_cast<NoteTrack*>(mCapturedTrack)->SetVelocity(newValue);
#ifdef EXPERIMENTAL_MIXER_BOARD
if (pMixerBoard)
// probably should modify UpdateGain to take a track that is
// either a WaveTrack or a NoteTrack.
pMixerBoard->UpdateGain((WaveTrack*)capturedTrack);
#endif
}
}
#endif
RefreshTrack(capturedTrack);
if (event.ButtonUp()) {
#ifdef EXPERIMENTAL_MIDI_OUT
if (capturedTrack->GetKind() == Track::Wave) {
#endif
MakeParentPushState(pan ? _("Moved pan slider") : _("Moved gain slider"),
pan ? _("Pan") : _("Gain"),
UndoPush::CONSOLIDATE);
#ifdef EXPERIMENTAL_MIDI_OUT
} else {
MakeParentPushState(_("Moved velocity slider"), _("Velocity"), UndoPush::CONSOLIDATE);
}
#endif
SetCapturedTrack( NULL );
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
void TrackPanel::HandleVelocitySlider(wxMouseEvent &event)
{
wxASSERT(mCapturedTrack->GetKind() == Track::Note);
NoteTrack *capturedTrack = (NoteTrack *) mCapturedTrack;
LWSlider *slider = mTrackInfo.VelocitySlider(capturedTrack, true);
slider->OnMouseEvent(event);
//If we have a double-click, do this...
if (event.LeftDClick())
mMouseCapture = IsUncaptured;
float newValue = slider->Get();
capturedTrack->SetVelocity(newValue);
MixerBoard* pMixerBoard = this->GetMixerBoard(); // Update mixer board, too.
if (pMixerBoard) {
pMixerBoard->UpdateVelocity(capturedTrack);
}
RefreshTrack(capturedTrack);
if (event.ButtonUp()) {
MakeParentPushState(_("Moved velocity slider"), _("Velocity"), UndoPush::CONSOLIDATE);
SetCapturedTrack(NULL);
}
}
#endif
// The tracks positions within the list have changed, so update the vertical
// ruler size for the track that triggered the event.
void TrackPanel::OnTrackListResized(wxCommandEvent & e)
@ -5107,21 +5110,11 @@ void TrackPanel::HandleLabelClick(wxMouseEvent & event)
{
wxRect midiRect;
#ifdef EXPERIMENTAL_MIDI_OUT
// this is an awful hack: make a NEW rectangle at an offset because
// MuteSoloFunc thinks buttons are located below some text, e.g.
// "Mono, 44100Hz 32-bit float", but this is not true for a Note track
wxRect muteSoloRect(rect);
muteSoloRect.y -= 34; // subtract the height of wave track text
if (MuteSoloFunc(t, muteSoloRect, event.m_x, event.m_y, false) ||
MuteSoloFunc(t, muteSoloRect, event.m_x, event.m_y, true))
if (isleft && (MuteSoloFunc(t, rect, event.m_x, event.m_y, false) ||
MuteSoloFunc(t, rect, event.m_x, event.m_y, true)))
return;
// this is a similar hack: GainFunc expects a Wave track slider, so it's
// looking in the wrong place. We pass it a bogus rectangle created when
// the slider was placed to "fake" GainFunc into finding the slider in
// its actual location.
if (GainFunc(t, ((NoteTrack *) t)->GetGainPlacementRect(),
event, event.m_x, event.m_y))
if (isleft && VelocityFunc(t, rect, event, event.m_x, event.m_y))
return;
#endif
mTrackInfo.GetTrackControlsRect(rect, midiRect);
@ -5287,6 +5280,23 @@ bool TrackPanel::PanFunc(Track * t, wxRect rect, wxMouseEvent &event,
return true;
}
#ifdef EXPERIMENTAL_MIDI_OUT
bool TrackPanel::VelocityFunc(Track * t, wxRect rect, wxMouseEvent &event,
int x, int y)
{
wxRect sliderRect;
mTrackInfo.GetVelocityRect(rect, sliderRect);
if (!sliderRect.Contains(x, y))
return false;
SetCapturedTrack(t, IsVelocitySliding);
mCapturedRect = rect;
HandleVelocitySlider(event);
return true;
}
#endif
/// Mute or solo the given track (t). If solo is true, we're
/// soloing, otherwise we're muting. Basically, check and see
/// whether x and y fall within the area of the appropriate button.
@ -5294,7 +5304,7 @@ bool TrackPanel::MuteSoloFunc(Track * t, wxRect rect, int x, int y,
bool solo)
{
wxRect buttonRect;
mTrackInfo.GetMuteSoloRect(rect, buttonRect, solo, HasSoloButton());
mTrackInfo.GetMuteSoloRect(rect, buttonRect, solo, HasSoloButton(), t);
if (!buttonRect.Contains(x, y))
return false;
@ -6182,6 +6192,11 @@ try
case IsPanSliding:
HandleSliders(event, true);
break;
#ifdef EXPERIMENTAL_MIDI_OUT
case IsVelocitySliding:
HandleVelocitySlider(event);
break;
#endif
case IsMinimizing:
HandleMinimizing(event);
break;
@ -7222,11 +7237,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec,
#ifdef USE_MIDI
else if (bIsNote) {
// Note tracks do not have text, e.g. "Mono, 44100Hz, 32-bit float", so
// Mute & Solo button goes higher. To preserve existing AudioTrack code,
// we move the buttons up by pretending track is higher (at lower y)
rect.y -= 34;
rect.height += 34;
wxRect midiRect;
mTrackInfo.GetTrackControlsRect(trackRect, midiRect);
// Offset by height of Solo/Mute buttons:
@ -7234,36 +7244,22 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec,
midiRect.height -= 21; // allow room for minimize button at bottom
#ifdef EXPERIMENTAL_MIDI_OUT
// the offset 2 is just to leave a little space between channel buttons
// and velocity slider (if any)
int h = ((NoteTrack *) t)->DrawLabelControls(*dc, midiRect) + 2;
((NoteTrack *)t)->DrawLabelControls(*dc, midiRect);
// Draw some lines for MuteSolo buttons:
if (rect.height > 84) {
AColor::Line(*dc, rect.x+48 , rect.y+50, rect.x+48, rect.y + 66);
// bevel below mute/solo
AColor::Line(*dc, rect.x, rect.y + 66, mTrackInfo.GetTrackInfoWidth(), rect.y + 66);
// Draw some lines for MuteSolo buttons (normally handled by DrawBordersWithin but not done for note tracks)
if (rect.height > 48) {
// Note: offset up by 34 units
AColor::Line(*dc, rect.x + 48, rect.y + 16, rect.x + 48, rect.y + 32); // between mute/solo
AColor::Line(*dc, rect.x, rect.y + 32, kTrackInfoWidth, rect.y + 32); // below mute/solo
}
mTrackInfo.DrawMuteSolo(dc, rect, t,
(captured && mMouseCapture == IsMuting), false, HasSoloButton());
mTrackInfo.DrawMuteSolo(dc, rect, t,
(captured && mMouseCapture == IsSoloing), true, HasSoloButton());
// place a volume control below channel buttons (this will
// Place a volume control below channel buttons (this will
// control an offset to midi velocity).
// DrawVelocitySlider places slider assuming this is a Wave track
// and using a large offset to leave room for other things,
// so here we make a fake rectangle as if it is for a Wave
// track, but it is offset to place the slider properly in
// a Note track. This whole placement thing should be redesigned
// to lay out different types of tracks and controls
wxRect gr; // gr is gain rectangle where slider is drawn
mTrackInfo.GetGainRect(rect, gr);
rect.y = rect.y + h - gr.y; // ultimately want slider at rect.y + h
rect.height = rect.height - h + gr.y;
// save for mouse hit detect:
((NoteTrack *) t)->SetGainPlacementRect(rect);
mTrackInfo.DrawVelocitySlider(dc, (NoteTrack *) t, rect);
mTrackInfo.DrawVelocitySlider(dc, (NoteTrack *)t, rect, captured);
#endif
}
#endif // USE_MIDI
@ -9015,6 +9011,22 @@ TrackInfo::TrackInfo(TrackPanel * pParentIn)
PAN_SLIDER);
mPanCaptured->SetDefaultValue(0.0);
#ifdef EXPERIMENTAL_MIDI_OUT
GetVelocityRect(rect, sliderRect);
/* i18n-hint: Title of the Velocity slider, used to adjust the volume of note tracks */
mVelocity = std::make_unique<LWSlider>(pParent, _("Velocity"),
wxPoint(sliderRect.x, sliderRect.y),
wxSize(sliderRect.width, sliderRect.height),
VEL_SLIDER);
mVelocity->SetDefaultValue(0.0);
mVelocityCaptured = std::make_unique<LWSlider>(pParent, _("Velocity"),
wxPoint(sliderRect.x, sliderRect.y),
wxSize(sliderRect.width, sliderRect.height),
VEL_SLIDER);
mVelocityCaptured->SetDefaultValue(0.0);
#endif
UpdatePrefs();
}
@ -9043,10 +9055,20 @@ void TrackInfo::GetTitleBarRect(const wxRect & rect, wxRect & dest) const
dest.height = kTrackInfoBtnSize;
}
void TrackInfo::GetMuteSoloRect(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton) const
void TrackInfo::GetMuteSoloRect(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton, const Track *pTrack) const
{
dest.x = rect.x ;
dest.x = rect.x;
#ifdef EXPERIMENTAL_MIDI_OUT
if (pTrack->GetKind() == Track::Note)
dest.y = rect.y + 16;
else
{
wxASSERT(pTrack->GetKind() == Track::Wave);
dest.y = rect.y + 50;
}
#else
dest.y = rect.y + 50;
#endif
dest.width = 48;
dest.height = kTrackInfoBtnSize;
@ -9076,6 +9098,16 @@ void TrackInfo::GetPanRect(const wxRect & rect, wxRect & dest) const
dest.height = 25;
}
#ifdef EXPERIMENTAL_MIDI_OUT
void TrackInfo::GetVelocityRect(const wxRect & rect, wxRect & dest) const
{
dest.x = rect.x + 7;
dest.y = rect.y + 100;
dest.width = 84;
dest.height = 25;
}
#endif
void TrackInfo::GetMinimizeRect(const wxRect & rect, wxRect &dest) const
{
const int kBlankWidth = kTrackInfoBtnSize + 4;
@ -9264,7 +9296,7 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t,
wxRect bev;
if( solo && !bHasSoloButton )
return;
GetMuteSoloRect(rect, bev, solo, bHasSoloButton);
GetMuteSoloRect(rect, bev, solo, bHasSoloButton, t);
bev.Inflate(-1, -1);
if (bev.y + bev.height >= rect.y + rect.height - 19)
@ -9342,27 +9374,6 @@ void TrackInfo::DrawMinimize(wxDC * dc, const wxRect & rect, Track * t, bool dow
AColor::BevelTrackInfo(*dc, !down, bev);
}
#ifdef EXPERIMENTAL_MIDI_OUT
void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect) const
{
wxRect gainRect;
int index = t->GetIndex();
//EnsureSufficientSliders(index);
GetGainRect(rect, gainRect);
if (gainRect.y + gainRect.height < rect.y + rect.height - 19) {
auto &gain = mGain; // mGains[index];
gain->SetStyle(VEL_SLIDER);
GainSlider(index)->Move(wxPoint(gainRect.x, gainRect.y));
GainSlider(index)->Set(t->GetVelocity());
GainSlider(index)->OnPaint(*dc
// , t->GetSelected()
);
}
}
#endif
void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect rect, bool captured) const
{
wxRect sliderRect;
@ -9378,6 +9389,18 @@ void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect rect, bool captured)
}
}
#ifdef EXPERIMENTAL_MIDI_OUT
void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool captured) const
{
wxRect sliderRect;
GetVelocityRect(rect, sliderRect);
if (sliderRect.y + sliderRect.height < rect.y + rect.height - 19) {
VelocitySlider(t, captured)->OnPaint(*dc);
}
}
#endif
LWSlider * TrackInfo::GainSlider(WaveTrack *t, bool captured) const
{
wxRect rect(kLeftInset, t->GetY() - pParent->GetViewInfo()->vpos + kTopInset, 1, t->GetHeight());
@ -9412,6 +9435,25 @@ LWSlider * TrackInfo::PanSlider(WaveTrack *t, bool captured) const
return (captured ? mPanCaptured : mPan).get();
}
#ifdef EXPERIMENTAL_MIDI_OUT
LWSlider * TrackInfo::VelocitySlider(NoteTrack *t, bool captured) const
{
wxRect rect(kLeftInset, t->GetY() - pParent->GetViewInfo()->vpos + kTopInset, 1, t->GetHeight());
wxRect sliderRect;
GetVelocityRect(rect, sliderRect);
wxPoint pos = sliderRect.GetPosition();
float velocity = t->GetVelocity();
mVelocity->Move(pos);
mVelocity->Set(velocity);
mVelocityCaptured->Move(pos);
mVelocityCaptured->Set(velocity);
return (captured ? mVelocityCaptured : mVelocity).get();
}
#endif
void TrackInfo::UpdatePrefs()
{
// Calculation of best font size depends on language, so it should be redone in case

View File

@ -92,10 +92,10 @@ private:
void DrawTitleBar(wxDC * dc, const wxRect & rect, Track * t, bool down) const;
void DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t, bool down, bool solo, bool bHasSoloButton) const;
void DrawVRuler(wxDC * dc, const wxRect & rect, Track * t) const;
#ifdef EXPERIMENTAL_MIDI_OUT
void DrawVelocitySlider(wxDC * dc, NoteTrack *t, wxRect rect) const ;
#endif
void DrawSliders(wxDC * dc, WaveTrack *t, wxRect rect, bool captured) const;
#ifdef EXPERIMENTAL_MIDI_OUT
void DrawVelocitySlider(wxDC * dc, NoteTrack *t, wxRect rect, bool captured) const;
#endif
// Draw the minimize button *and* the sync-lock track icon, if necessary.
void DrawMinimize(wxDC * dc, const wxRect & rect, Track * t, bool down) const;
@ -103,9 +103,13 @@ private:
void GetTrackControlsRect(const wxRect & rect, wxRect &dest) const;
void GetCloseBoxRect(const wxRect & rect, wxRect &dest) const;
void GetTitleBarRect(const wxRect & rect, wxRect &dest) const;
void GetMuteSoloRect(const wxRect & rect, wxRect &dest, bool solo, bool bHasSoloButton) const;
void GetMuteSoloRect(const wxRect & rect, wxRect &dest, bool solo, bool bHasSoloButton,
const Track *pTrack) const;
void GetGainRect(const wxRect & rect, wxRect &dest) const;
void GetPanRect(const wxRect & rect, wxRect &dest) const;
#ifdef EXPERIMENTAL_MIDI_OUT
void GetVelocityRect(const wxRect & rect, wxRect &dest) const;
#endif
void GetMinimizeRect(const wxRect & rect, wxRect &dest) const;
void GetSyncLockIconRect(const wxRect & rect, wxRect &dest) const;
@ -114,7 +118,7 @@ public:
LWSlider * PanSlider(WaveTrack *t, bool captured = false) const;
#ifdef EXPERIMENTAL_MIDI_OUT
LWSlider *GainSlider(int index) const;
LWSlider * VelocitySlider(NoteTrack *t, bool captured = false) const;
#endif
private:
@ -124,6 +128,9 @@ private:
wxFont mFont;
std::unique_ptr<LWSlider>
mGainCaptured, mPanCaptured, mGain, mPan;
#ifdef EXPERIMENTAL_MIDI_OUT
std::unique_ptr<LWSlider> mVelocityCaptured, mVelocity;
#endif
friend class TrackPanel;
};
@ -415,6 +422,9 @@ protected:
virtual void HandleMutingSoloing(wxMouseEvent & event, bool solo);
virtual void HandleMinimizing(wxMouseEvent & event);
virtual void HandleSliders(wxMouseEvent &event, bool pan);
#ifdef EXPERIMENTAL_MIDI_OUT
virtual void HandleVelocitySlider(wxMouseEvent &event);
#endif
// These *Func methods are used in TrackPanel::HandleLabelClick to set up
@ -434,6 +444,10 @@ protected:
int x, int y);
virtual bool PanFunc(Track * t, wxRect rect, wxMouseEvent &event,
int x, int y);
#ifdef EXPERIMENTAL_MIDI_OUT
virtual bool VelocityFunc(Track * t, wxRect rect, wxMouseEvent &event,
int x, int y);
#endif
virtual void MakeParentRedrawScrollbars();
@ -747,6 +761,9 @@ protected:
IsStretching,
#endif
IsZooming,
#ifdef EXPERIMENTAL_MIDI_OUT
IsVelocitySliding,
#endif
};

View File

@ -54,6 +54,7 @@ enum CommandFlag : unsigned long long
PausedFlag = 0x200000000ULL, // jkc
NotPausedFlag = 0x400000000ULL, // jkc
HasWaveDataFlag = 0x800000000ULL, // jkc
PlayableTracksExistFlag = 0x1000000000ULL,
NoFlagsSpecifed = ~0ULL
};