From 1d1dded9bad3cd25e0cf11480c37fd0a360e371c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 15:02:28 -0400 Subject: [PATCH 01/13] TrackInfo::SetTrackInfoFont is static --- src/TrackPanel.cpp | 12 +++++++----- src/TrackPanel.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index fbd6af18e..2a353c0ac 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -9007,10 +9007,12 @@ void TrackInfo::GetMidiControlsRect(const wxRect & rect, wxRect & dest) } #endif +wxFont TrackInfo::gFont; + /// \todo Probably should move to 'Utils.cpp'. -void TrackInfo::SetTrackInfoFont(wxDC * dc) const +void TrackInfo::SetTrackInfoFont(wxDC * dc) { - dc->SetFont(mFont); + dc->SetFont(gFont); } void TrackInfo::DrawBordersWithin @@ -9375,18 +9377,18 @@ void TrackInfo::UpdatePrefs() // the language preference changed. int fontSize = 10; - mFont.Create(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); + gFont.Create(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); int allowableWidth = GetTrackInfoWidth() - 2; // 2 to allow for left/right borders int textWidth, textHeight; do { - mFont.SetPointSize(fontSize); + gFont.SetPointSize(fontSize); pParent->GetTextExtent(_("Stereo, 999999Hz"), &textWidth, &textHeight, NULL, NULL, - &mFont); + &gFont); fontSize--; } while (textWidth >= allowableWidth); } diff --git a/src/TrackPanel.h b/src/TrackPanel.h index afddf8624..ffdaae8db 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -85,7 +85,7 @@ public: private: int GetTrackInfoWidth() const; - void SetTrackInfoFont(wxDC *dc) const; + static void SetTrackInfoFont(wxDC *dc); void DrawBackground(wxDC * dc, const wxRect & rect, bool bSelected, bool bHasMuteSolo, const int labelw, const int vrul) const; @@ -135,7 +135,7 @@ private: void UpdatePrefs(); TrackPanel * pParent; - wxFont mFont; + static wxFont gFont; std::unique_ptr mGainCaptured, mPanCaptured, mGain, mPan; #ifdef EXPERIMENTAL_MIDI_OUT From b15bf441ec6afbb833cdeba68fa6590fc4d5abfe Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 16:54:12 -0400 Subject: [PATCH 02/13] Static TrackInfo slider accessors, const Track* arguments --- src/Menus.cpp | 12 ++-- src/TrackPanel.cpp | 154 ++++++++++++++++++++++++++---------------- src/TrackPanel.h | 34 +++++++--- src/widgets/ASlider.h | 2 + 4 files changed, 127 insertions(+), 75 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index d28a4b54c..841b322c4 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -3657,7 +3657,7 @@ void AudacityProject::OnTrackPan() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->PanSlider(wt); + LWSlider *slider = mTrackPanel->PanSlider(wt); if (slider->ShowDialog()) { SetTrackPan(wt, slider); } @@ -3671,7 +3671,7 @@ void AudacityProject::OnTrackPanLeft() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->PanSlider(wt); + LWSlider *slider = mTrackPanel->PanSlider(wt); slider->Decrease(1); SetTrackPan(wt, slider); } @@ -3684,7 +3684,7 @@ void AudacityProject::OnTrackPanRight() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->PanSlider(wt); + LWSlider *slider = mTrackPanel->PanSlider(wt); slider->Increase(1); SetTrackPan(wt, slider); } @@ -3698,7 +3698,7 @@ void AudacityProject::OnTrackGain() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->GainSlider(wt); + LWSlider *slider = mTrackPanel->GainSlider(wt); if (slider->ShowDialog()) { SetTrackGain(wt, slider); } @@ -3712,7 +3712,7 @@ void AudacityProject::OnTrackGainInc() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->GainSlider(wt); + LWSlider *slider = mTrackPanel->GainSlider(wt); slider->Increase(1); SetTrackGain(wt, slider); } @@ -3725,7 +3725,7 @@ void AudacityProject::OnTrackGainDec() } const auto wt = static_cast(track); - LWSlider *slider = mTrackPanel->GetTrackInfo()->GainSlider(wt); + LWSlider *slider = mTrackPanel->GainSlider(wt); slider->Decrease(1); SetTrackGain(wt, slider); } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 2a353c0ac..ca5ca70ff 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -570,6 +570,32 @@ TrackPanel::~TrackPanel() DeleteMenus(); } +LWSlider *TrackPanel::GainSlider( const WaveTrack *wt ) +{ + auto rect = FindTrackRect( wt, true ); + wxRect sliderRect; + TrackInfo::GetGainRect( rect.GetTopLeft(), sliderRect ); + return TrackInfo::GainSlider(sliderRect, wt, false, this); +} + +LWSlider *TrackPanel::PanSlider( const WaveTrack *wt ) +{ + auto rect = FindTrackRect( wt, true ); + wxRect sliderRect; + TrackInfo::GetPanRect( rect.GetTopLeft(), sliderRect ); + return TrackInfo::PanSlider(sliderRect, wt, false, this); +} + +#ifdef EXPERIMENTAL_MIDI_OUT +LWSlider *TrackPanel::VelocitySlider( const NoteTrack *nt ) +{ + auto rect = FindTrackRect( nt, true ); + wxRect sliderRect; + TrackInfo::GetVelocityRect( rect.GetTopLeft(), sliderRect ); + return TrackInfo::VelocitySlider(sliderRect, nt, false, this); +} +#endif + SelectionState &TrackPanel::GetSelectionState() { return GetProject()->GetSelectionState(); @@ -4865,10 +4891,17 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan) // is displayed, but it doesn't hurt to do this for all plats. WaveTrack *capturedTrack = (WaveTrack *) mCapturedTrack; - if (pan) - slider = mTrackInfo.PanSlider(capturedTrack, true); - else - slider = mTrackInfo.GainSlider(capturedTrack, true); + auto rect = FindTrackRect( capturedTrack, true ); + if (pan) { + wxRect sliderRect; + TrackInfo::GetPanRect(rect.GetTopLeft(), sliderRect); + slider = mTrackInfo.PanSlider(sliderRect, capturedTrack, true, this); + } + else { + wxRect sliderRect; + TrackInfo::GetGainRect(rect.GetTopLeft(), sliderRect); + slider = mTrackInfo.GainSlider(sliderRect, capturedTrack, true, this); + } slider->OnMouseEvent(event); @@ -4923,7 +4956,10 @@ void TrackPanel::HandleVelocitySlider(wxMouseEvent &event) wxASSERT(mCapturedTrack->GetKind() == Track::Note); NoteTrack *capturedTrack = static_cast(mCapturedTrack); - LWSlider *slider = mTrackInfo.VelocitySlider(capturedTrack, true); + auto rect = FindTrackRect( capturedTrack, true ); + wxRect sliderRect; + TrackInfo::GetVelocityRect(rect.GetTopLeft(), sliderRect); + auto slider = mTrackInfo.VelocitySlider(sliderRect, capturedTrack, true, this); slider->OnMouseEvent(event); @@ -8715,7 +8751,7 @@ TrackPanel::FoundCell TrackPanel::FindCell(int mouseX, int mouseY) /// This finds the rectangle of a given track, either the /// of the label 'adornment' or the track itself -wxRect TrackPanel::FindTrackRect(Track * target, bool label) +wxRect TrackPanel::FindTrackRect( const Track * target, bool label ) { if (!target) { return { 0, 0, 0, 0 }; @@ -8813,11 +8849,6 @@ TrackInfo::TrackInfo(TrackPanel * pParentIn) { pParent = pParentIn; - mGain = NULL; - mGainCaptured=NULL; - mPan = NULL; - mPanCaptured=NULL; - ReCreateSliders(); UpdatePrefs(); @@ -8834,48 +8865,48 @@ void TrackInfo::ReCreateSliders(){ float defPos = 1.0; /* i18n-hint: Title of the Gain slider, used to adjust the volume */ - mGain = std::make_unique(pParent, _("Gain"), + gGain = std::make_unique(pParent, _("Gain"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), DB_SLIDER); - mGain->SetDefaultValue(defPos); + gGain->SetDefaultValue(defPos); - mGainCaptured = std::make_unique(pParent, _("Gain"), + gGainCaptured = std::make_unique(pParent, _("Gain"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), DB_SLIDER); - mGainCaptured->SetDefaultValue(defPos); + gGainCaptured->SetDefaultValue(defPos); GetPanRect(point, sliderRect); defPos = 0.0; /* i18n-hint: Title of the Pan slider, used to move the sound left or right */ - mPan = std::make_unique(pParent, _("Pan"), + gPan = std::make_unique(pParent, _("Pan"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), PAN_SLIDER); - mPan->SetDefaultValue(defPos); + gPan->SetDefaultValue(defPos); - mPanCaptured = std::make_unique(pParent, _("Pan"), + gPanCaptured = std::make_unique(pParent, _("Pan"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), PAN_SLIDER); - mPanCaptured->SetDefaultValue(defPos); + gPanCaptured->SetDefaultValue(defPos); #ifdef EXPERIMENTAL_MIDI_OUT GetVelocityRect(point, sliderRect); /* i18n-hint: Title of the Velocity slider, used to adjust the volume of note tracks */ - mVelocity = std::make_unique(pParent, _("Velocity"), + gVelocity = std::make_unique(pParent, _("Velocity"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), VEL_SLIDER); - mVelocity->SetDefaultValue(0.0); - mVelocityCaptured = std::make_unique(pParent, _("Velocity"), + gVelocity->SetDefaultValue(0.0); + gVelocityCaptured = std::make_unique(pParent, _("Velocity"), wxPoint(sliderRect.x, sliderRect.y), wxSize(sliderRect.width, sliderRect.height), VEL_SLIDER); - mVelocityCaptured->SetDefaultValue(0.0); + gVelocityCaptured->SetDefaultValue(0.0); #endif } @@ -9275,11 +9306,11 @@ void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect rect, bool captured) GetGainRect(rect.GetTopLeft(), sliderRect); if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) - GainSlider(t, captured)->OnPaint(*dc); + GainSlider(sliderRect, t, captured, pParent)->OnPaint(*dc); GetPanRect(rect.GetTopLeft(), sliderRect); if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) - PanSlider(t, captured)->OnPaint(*dc); + PanSlider(sliderRect, t, captured, pParent)->OnPaint(*dc); } #ifdef EXPERIMENTAL_MIDI_OUT @@ -9289,7 +9320,7 @@ void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool cap GetVelocityRect( rect.GetTopLeft(), sliderRect ); if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) { - VelocitySlider(t, captured)->OnPaint(*dc); + VelocitySlider(sliderRect, t, captured, pParent)->OnPaint(*dc); } } #endif @@ -9315,59 +9346,64 @@ unsigned TrackInfo::DefaultWaveTrackHeight() return (unsigned) std::max( needed, (int) Track::DefaultHeight ); } -LWSlider * TrackInfo::GainSlider(WaveTrack *t, bool captured) const -{ - wxPoint topLeft{ - kLeftMargin, t->GetY() - pParent->GetViewInfo()->vpos + kTopMargin }; - wxRect sliderRect; - GetGainRect(topLeft, sliderRect); +std::unique_ptr + TrackInfo::gGainCaptured + , TrackInfo::gPanCaptured + , TrackInfo::gGain + , TrackInfo::gPan +#ifdef EXPERIMENTAL_MIDI_OUT + , TrackInfo::gVelocityCaptured + , TrackInfo::gVelocity +#endif +; +LWSlider * TrackInfo::GainSlider +(const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent) +{ wxPoint pos = sliderRect.GetPosition(); float gain = t->GetGain(); - mGain->Move(pos); - mGain->Set(gain); - mGainCaptured->Move(pos); - mGainCaptured->Set(gain); + gGain->Move(pos); + gGain->Set(gain); + gGainCaptured->Move(pos); + gGainCaptured->Set(gain); - return (captured ? mGainCaptured : mGain).get(); + auto slider = (captured ? gGainCaptured : gGain).get(); + slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + return slider; } -LWSlider * TrackInfo::PanSlider(WaveTrack *t, bool captured) const +LWSlider * TrackInfo::PanSlider +(const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent) { - wxPoint topLeft{ - kLeftMargin, t->GetY() - pParent->GetViewInfo()->vpos + kTopMargin }; - wxRect sliderRect; - GetPanRect(topLeft, sliderRect); - wxPoint pos = sliderRect.GetPosition(); float pan = t->GetPan(); - mPan->Move(pos); - mPan->Set(pan); - mPanCaptured->Move(pos); - mPanCaptured->Set(pan); + gPan->Move(pos); + gPan->Set(pan); + gPanCaptured->Move(pos); + gPanCaptured->Set(pan); - return (captured ? mPanCaptured : mPan).get(); + auto slider = (captured ? gPanCaptured : gPan).get(); + slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + return slider; } #ifdef EXPERIMENTAL_MIDI_OUT -LWSlider * TrackInfo::VelocitySlider(NoteTrack *t, bool captured) const +LWSlider * TrackInfo::VelocitySlider +(const wxRect &sliderRect, const NoteTrack *t, bool captured, wxWindow *pParent) { - wxPoint topLeft{ - kLeftMargin, t->GetY() - pParent->GetViewInfo()->vpos + kTopMargin }; - wxRect sliderRect; - GetVelocityRect(topLeft, sliderRect); - wxPoint pos = sliderRect.GetPosition(); float velocity = t->GetVelocity(); - mVelocity->Move(pos); - mVelocity->Set(velocity); - mVelocityCaptured->Move(pos); - mVelocityCaptured->Set(velocity); + gVelocity->Move(pos); + gVelocity->Set(velocity); + gVelocityCaptured->Move(pos); + gVelocityCaptured->Set(velocity); - return (captured ? mVelocityCaptured : mVelocity).get(); + auto slider = (captured ? gVelocityCaptured : gVelocity).get(); + slider->SetParent( pParent ? pParent : ::GetActiveProject() ); + return slider; } #endif diff --git a/src/TrackPanel.h b/src/TrackPanel.h index ffdaae8db..bc20b5fff 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -124,11 +124,17 @@ public: static unsigned DefaultNoteTrackHeight(); static unsigned DefaultWaveTrackHeight(); - LWSlider * GainSlider(WaveTrack *t, bool captured = false) const; - LWSlider * PanSlider(WaveTrack *t, bool captured = false) const; + static LWSlider * GainSlider + (const wxRect &sliderRect, const WaveTrack *t, bool captured, + wxWindow *pParent); + static LWSlider * PanSlider + (const wxRect &sliderRect, const WaveTrack *t, bool captured, + wxWindow *pParent); #ifdef EXPERIMENTAL_MIDI_OUT - LWSlider * VelocitySlider(NoteTrack *t, bool captured = false) const; + static LWSlider * VelocitySlider + (const wxRect &sliderRect, const NoteTrack *t, bool captured, + wxWindow *pParent); #endif private: @@ -136,10 +142,10 @@ private: TrackPanel * pParent; static wxFont gFont; - std::unique_ptr - mGainCaptured, mPanCaptured, mGain, mPan; + static std::unique_ptr + gGainCaptured, gPanCaptured, gGain, gPan; #ifdef EXPERIMENTAL_MIDI_OUT - std::unique_ptr mVelocityCaptured, mVelocity; + static std::unique_ptr gVelocityCaptured, gVelocity; #endif friend class TrackPanel; @@ -538,7 +544,7 @@ protected: // If label, rectangle includes track control panel only. // If !label, rectangle includes all of that, and the vertical ruler, and // the proper track area. - virtual wxRect FindTrackRect(Track * target, bool label); + virtual wxRect FindTrackRect( const Track * target, bool label ); virtual int GetVRulerWidth() const; virtual int GetVRulerOffset() const { return mTrackInfo.GetTrackInfoWidth(); } @@ -593,9 +599,17 @@ protected: virtual wxString TrackSubText(WaveTrack *t); TrackInfo mTrackInfo; - public: - TrackInfo *GetTrackInfo() { return &mTrackInfo; } - const TrackInfo *GetTrackInfo() const { return &mTrackInfo; } + +public: + + LWSlider *GainSlider( const WaveTrack *wt ); + LWSlider *PanSlider( const WaveTrack *wt ); +#ifdef EXPERIMENTAL_MIDI_OUT + LWSlider *VelocitySlider( const NoteTrack *nt ); +#endif + + TrackInfo *GetTrackInfo() { return &mTrackInfo; } + const TrackInfo *GetTrackInfo() const { return &mTrackInfo; } protected: TrackPanelListener *mListener; diff --git a/src/widgets/ASlider.h b/src/widgets/ASlider.h index 5ffdd2f33..977a6f93c 100644 --- a/src/widgets/ASlider.h +++ b/src/widgets/ASlider.h @@ -156,6 +156,8 @@ class LWSlider static void DeleteSharedTipPanel(); + void SetParent(wxWindow *parent) { mParent = parent; } + private: wxString GetTip(float value) const; From 18b3bc0600cabf25e6c81aa014d7edb881beefff Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 13:39:23 -0400 Subject: [PATCH 03/13] Separate functions defining the horizontal bounds of TCP items --- src/TrackPanel.cpp | 113 +++++++++++++++++++++++++++++++++------------ src/TrackPanel.h | 27 ++++++++++- 2 files changed, 108 insertions(+), 32 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index ca5ca70ff..7131fab0c 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -8916,30 +8916,65 @@ int TrackInfo::GetTrackInfoWidth() const return kTrackInfoWidth; } -void TrackInfo::GetCloseBoxRect(const wxRect & rect, wxRect & dest) +void TrackInfo::GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest ) { dest.x = rect.x; + dest.width = kTrackInfoBtnSize; +} + +void TrackInfo::GetCloseBoxRect(const wxRect & rect, wxRect & dest) +{ + GetCloseBoxHorizontalBounds( rect, dest ); auto results = CalcItemY( commonTrackTCPLines, kItemBarButtons ); dest.y = rect.y + results.first; - dest.width = kTrackInfoBtnSize; dest.height = results.second; } +static const int TitleSoloBorderOverlap = 1; + +void TrackInfo::GetTitleBarHorizontalBounds( const wxRect & rect, wxRect &dest ) +{ + // to right of CloseBoxRect, plus a little more + wxRect closeRect; + GetCloseBoxHorizontalBounds( rect, closeRect ); + dest.x = rect.x + closeRect.width + 1; + dest.width = rect.x + rect.width - dest.x + TitleSoloBorderOverlap; +} + void TrackInfo::GetTitleBarRect(const wxRect & rect, wxRect & dest) { - // to right of CloseBoxRect, plus a little more - dest.x = rect.x + kTrackInfoBtnSize + 1; + GetTitleBarHorizontalBounds( rect, dest ); auto results = CalcItemY( commonTrackTCPLines, kItemBarButtons ); dest.y = rect.y + results.first; - // PRL: + 1? Really? - dest.width = rect.x + rect.width - dest.x + 1; dest.height = results.second; } -void TrackInfo::GetMuteSoloRect(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton, const Track *pTrack) +void TrackInfo::GetNarrowMuteHorizontalBounds( const wxRect & rect, wxRect &dest ) { - dest.x = rect.x; + dest.width = rect.width / 2 + 1; +} + +void TrackInfo::GetNarrowSoloHorizontalBounds( const wxRect & rect, wxRect &dest ) +{ + wxRect muteRect; + GetNarrowMuteHorizontalBounds( rect, muteRect ); + dest.x = rect.x + muteRect.width; + dest.width = rect.width - muteRect.width + TitleSoloBorderOverlap; +} + +void TrackInfo::GetWideMuteSoloHorizontalBounds( const wxRect & rect, wxRect &dest ) +{ + // Larger button, symmetrically placed intended. + // On windows this gives 15 pixels each side. + dest.width = rect.width - 2 * kTrackInfoBtnSize + 6; + dest.x = rect.x + kTrackInfoBtnSize -3; +} + +void TrackInfo::GetMuteSoloRect +(const wxRect & rect, wxRect & dest, bool solo, bool bHasSoloButton, + const Track *pTrack) +{ auto resultsM = CalcItemY( getTCPLines( *pTrack ), kItemMute ); auto resultsS = CalcItemY( getTCPLines( *pTrack ), kItemSolo ); @@ -8953,19 +8988,13 @@ void TrackInfo::GetMuteSoloRect(const wxRect & rect, wxRect & dest, bool solo, b if( bNarrow ) { - dest.width = rect.width / 2 + 1; - if( solo ) { - dest.x += dest.width; - dest.width = rect.width - dest.width+1; - } + if( solo ) + GetNarrowSoloHorizontalBounds( rect, dest ); + else + GetNarrowMuteHorizontalBounds( rect, dest ); } else - { - // Larger button, symmetrically placed intended. - // On windows this gives 15 pixels each side. - dest.width = rect.width - 2 * kTrackInfoBtnSize + 6; - dest.x = rect.x + kTrackInfoBtnSize -3; - } + GetWideMuteSoloHorizontalBounds( rect, dest ); if( bSameRow || !solo ) dest.y = rect.y + yMute; @@ -8974,12 +9003,17 @@ void TrackInfo::GetMuteSoloRect(const wxRect & rect, wxRect & dest, bool solo, b } -void TrackInfo::GetGainRect(const wxPoint &topleft, wxRect & dest) +void TrackInfo::GetSliderHorizontalBounds( const wxPoint &topleft, wxRect &dest ) { dest.x = topleft.x + 6; + dest.width = kTrackInfoSliderWidth; +} + +void TrackInfo::GetGainRect(const wxPoint &topleft, wxRect & dest) +{ + GetSliderHorizontalBounds( topleft, dest ); auto results = CalcItemY( waveTrackTCPLines, kItemGain ); dest.y = topleft.y + results.first; - dest.width = kTrackInfoSliderWidth; dest.height = results.second; } @@ -8993,45 +9027,64 @@ void TrackInfo::GetPanRect(const wxPoint &topleft, wxRect & dest) #ifdef EXPERIMENTAL_MIDI_OUT void TrackInfo::GetVelocityRect(const wxPoint &topleft, wxRect & dest) { - dest.x = topleft.x + 6; + GetSliderHorizontalBounds( topleft, dest ); auto results = CalcItemY( noteTrackTCPLines, kItemVelocity ); dest.y = topleft.y + results.first; - dest.width = kTrackInfoSliderWidth; dest.height = results.second; } #endif -void TrackInfo::GetMinimizeRect(const wxRect & rect, wxRect &dest) +void TrackInfo::GetMinimizeHorizontalBounds( const wxRect &rect, wxRect &dest ) { const int space = 0;// was 3. dest.x = rect.x + space; + + wxRect syncLockRect; + GetSyncLockHorizontalBounds( rect, syncLockRect ); + + // Width is rect.width less space on left for track select + // and on right for sync-lock icon. + dest.width = rect.width - (space + syncLockRect.width); +} + +void TrackInfo::GetMinimizeRect(const wxRect & rect, wxRect &dest) +{ + GetMinimizeHorizontalBounds( rect, dest ); auto results = CalcBottomItemY ( commonTrackTCPBottomLines, kItemMinimize, rect.height); dest.y = rect.y + results.first; - // Width is rect.width less space on left for track select - // and on right for sync-lock icon. - dest.width = rect.width - (space + kTrackInfoBtnSize); dest.height = results.second; } +void TrackInfo::GetSyncLockHorizontalBounds( const wxRect &rect, wxRect &dest ) +{ + dest.width = kTrackInfoBtnSize; + dest.x = rect.x + rect.width - dest.width; +} + void TrackInfo::GetSyncLockIconRect(const wxRect & rect, wxRect &dest) { - dest.x = rect.x + rect.width - kTrackInfoBtnSize; // to right of minimize button + GetSyncLockHorizontalBounds( rect, dest ); auto results = CalcBottomItemY ( commonTrackTCPBottomLines, kItemSyncLock, rect.height); dest.y = rect.y + results.first; - dest.width = kTrackInfoBtnSize; dest.height = results.second; } #ifdef USE_MIDI -void TrackInfo::GetMidiControlsRect(const wxRect & rect, wxRect & dest) +void TrackInfo::GetMidiControlsHorizontalBounds +( const wxRect &rect, wxRect &dest ) { dest.x = rect.x + 1; // To center slightly // PRL: TODO: kMidiCellWidth is defined in terms of the other constant // kTrackInfoWidth but I am trying to avoid use of that constant. // Can cell width be computed from dest.width instead? dest.width = kMidiCellWidth * 4; +} + +void TrackInfo::GetMidiControlsRect(const wxRect & rect, wxRect & dest) +{ + GetMidiControlsHorizontalBounds( rect, dest ); auto results = CalcItemY( noteTrackTCPLines, kItemMidiControlsRect ); dest.y = rect.y + results.first; dest.height = results.second; diff --git a/src/TrackPanel.h b/src/TrackPanel.h index bc20b5fff..3707dfd6d 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -102,18 +102,41 @@ private: // Draw the minimize button *and* the sync-lock track icon, if necessary. void DrawMinimize(wxDC * dc, const wxRect & rect, Track * t, bool down) const; + static void GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest ); static void GetCloseBoxRect(const wxRect & rect, wxRect &dest); + + static void GetTitleBarHorizontalBounds( const wxRect & rect, wxRect &dest ); static void GetTitleBarRect(const wxRect & rect, wxRect &dest); - static void GetMuteSoloRect(const wxRect & rect, wxRect &dest, bool solo, bool bHasSoloButton, - const Track *pTrack); + + static void GetNarrowMuteHorizontalBounds + ( const wxRect & rect, wxRect &dest ); + static void GetNarrowSoloHorizontalBounds + ( const wxRect & rect, wxRect &dest ); + static void GetWideMuteSoloHorizontalBounds + ( const wxRect & rect, wxRect &dest ); + static void GetMuteSoloRect + (const wxRect & rect, wxRect &dest, bool solo, bool bHasSoloButton, + const Track *pTrack); + + static void GetSliderHorizontalBounds( const wxPoint &topleft, wxRect &dest ); + static void GetGainRect(const wxPoint & topLeft, wxRect &dest); + static void GetPanRect(const wxPoint & topLeft, wxRect &dest); + #ifdef EXPERIMENTAL_MIDI_OUT static void GetVelocityRect(const wxPoint & topLeft, wxRect &dest); #endif + + static void GetMinimizeHorizontalBounds( const wxRect &rect, wxRect &dest ); static void GetMinimizeRect(const wxRect & rect, wxRect &dest); + + static void GetSyncLockHorizontalBounds( const wxRect &rect, wxRect &dest ); static void GetSyncLockIconRect(const wxRect & rect, wxRect &dest); + #ifdef USE_MIDI + static void GetMidiControlsHorizontalBounds + ( const wxRect &rect, wxRect &dest ); static void GetMidiControlsRect(const wxRect & rect, wxRect &dest); #endif From 98b24cd6b9715728d3021c8e0d26f5a791f5fa5d Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 19:03:09 -0400 Subject: [PATCH 04/13] Redo calculation of default track heights --- src/TrackPanel.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 7131fab0c..29cd94798 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5112,13 +5112,17 @@ const TCPLine noteTrackTCPLines[] = { { 0, 0, 0 } }; -int totalTCPLines( const TCPLine *pLines ) +int totalTCPLines( const TCPLine *pLines, bool omitLastExtra ) { int total = 0; + int lastExtra = 0; while ( pLines->items ) { - total += pLines->height + pLines->extraSpace; + lastExtra = pLines->extraSpace; + total += pLines->height + lastExtra; ++pLines; } + if (omitLastExtra) + total -= lastExtra; return total; } @@ -9378,25 +9382,25 @@ void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool cap } #endif -unsigned TrackInfo::DefaultNoteTrackHeight() +namespace { +unsigned DefaultTrackHeight( const TCPLine topLines[] ) { - // Just high enough that the velocity slider is just above the Minimize - // button, as for default sized Wave track int needed = kTopMargin + kBottomMargin + - totalTCPLines( noteTrackTCPLines ) + - totalTCPLines( commonTrackTCPBottomLines ) - - kTrackInfoSliderExtra; + totalTCPLines( topLines, true ) + + totalTCPLines( commonTrackTCPBottomLines, false ) + 1; return (unsigned) std::max( needed, (int) Track::DefaultHeight ); } +} + +unsigned TrackInfo::DefaultNoteTrackHeight() +{ + return DefaultTrackHeight( noteTrackTCPLines ); +} unsigned TrackInfo::DefaultWaveTrackHeight() { - int needed = - kTopMargin + kBottomMargin + - totalTCPLines( waveTrackTCPLines ) + - totalTCPLines( commonTrackTCPBottomLines ); - return (unsigned) std::max( needed, (int) Track::DefaultHeight ); + return DefaultTrackHeight( waveTrackTCPLines ); } std::unique_ptr From e554f0cdc6eb627dbab28bdd05bb7420880d1785 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 13 Jun 2017 08:05:17 -0400 Subject: [PATCH 05/13] TrackPanel::HasSoloButton is static and public --- src/TrackPanel.cpp | 4 +++- src/TrackPanel.h | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 29cd94798..394370204 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -773,11 +773,13 @@ void TrackPanel::UpdateVirtualStereoOrder() } #endif +wxString TrackPanel::gSoloPref; + void TrackPanel::UpdatePrefs() { gPrefs->Read(wxT("/GUI/AutoScroll"), &mViewInfo->bUpdateTrackIndicator, true); - gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple")); + gPrefs->Read(wxT("/GUI/Solo"), &gSoloPref, wxT("Simple")); #ifdef EXPERIMENTAL_OUTPUT_DISPLAY bool temp = WaveTrack::mMonoAsVirtualStereo; diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 3707dfd6d..9fc547ec9 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -612,9 +612,12 @@ protected: #ifdef EXPERIMENTAL_OUTPUT_DISPLAY void UpdateVirtualStereoOrder(); #endif - // Accessors... - virtual bool HasSoloButton(){ return mSoloPref!=wxT("None");} +public: + // Accessors... + static bool HasSoloButton(){ return gSoloPref!=wxT("None");} + +protected: //JKC: These two belong in the label track. int mLabelTrackStartXPos; int mLabelTrackStartYPos; @@ -876,7 +879,7 @@ public: protected: - wxString mSoloPref; + static wxString gSoloPref; // Keeps track of extra fractional vertical scroll steps double mVertScrollRemainder; From ba014f042a6f2625915a0f90bd43c5c08f134b40 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 12:28:20 -0400 Subject: [PATCH 06/13] Add a slot for drawing functions to the TCP lines table --- src/TrackPanel.cpp | 122 +++++++++++++++++++++++++++++++++------------ src/TrackPanel.h | 12 +++++ 2 files changed, 102 insertions(+), 32 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 394370204..87e578a60 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5039,6 +5039,21 @@ void TrackPanel::OnContextMenu(wxContextMenuEvent & WXUNUSED(event)) OnTrackMenu(); } +struct TrackInfo::TCPLine { + using DrawFunction = void (*)( + wxDC *dc, + const wxRect &rect, + const Track *maybeNULL, + int pressed, // a value from MouseCaptureEnum; TODO: make it bool + bool captured + ); + + unsigned items; // a bitwise OR of values of the enum above + int height; + int extraSpace; + DrawFunction drawFunction; +}; + namespace { enum : unsigned { @@ -5058,63 +5073,58 @@ enum : unsigned { kHighestBottomItem = kItemMinimize, }; -struct TCPLine { - unsigned items; // a bitwise OR of values of the enum above - int height; - int extraSpace; -}; #ifdef EXPERIMENTAL_DA #define TITLE_ITEMS \ - { kItemBarButtons, kTrackInfoBtnSize, 4 }, + { kItemBarButtons, kTrackInfoBtnSize, 4, nullptr }, // DA: Has Mute and Solo on separate lines. #define MUTE_SOLO_ITEMS(extra) \ - { kItemMute, kTrackInfoBtnSize + 1, 1 }, \ - { kItemSolo, kTrackInfoBtnSize + 1, extra }, + { kItemMute, kTrackInfoBtnSize + 1, 1, nullptr }, \ + { kItemSolo, kTrackInfoBtnSize + 1, extra, nullptr }, // DA: Does not have status information for a track. #define STATUS_ITEMS #else #define TITLE_ITEMS \ - { kItemBarButtons, kTrackInfoBtnSize, 0 }, + { kItemBarButtons, kTrackInfoBtnSize, 0, nullptr }, #define MUTE_SOLO_ITEMS(extra) \ - { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra }, + { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra, nullptr }, #define STATUS_ITEMS \ - { kItemStatusInfo1, 12, 0 }, \ - { kItemStatusInfo2, 12, 0 }, + { kItemStatusInfo1, 12, 0, nullptr }, \ + { kItemStatusInfo2, 12, 0, nullptr }, #endif #define COMMON_ITEMS \ TITLE_ITEMS -const TCPLine commonTrackTCPLines[] = { +const TrackInfo::TCPLine commonTrackTCPLines[] = { COMMON_ITEMS - { 0, 0, 0 } + { 0, 0, 0, nullptr } }; -const TCPLine waveTrackTCPLines[] = { +const TrackInfo::TCPLine waveTrackTCPLines[] = { COMMON_ITEMS MUTE_SOLO_ITEMS(2) - { kItemGain, kTrackInfoSliderHeight, kTrackInfoSliderExtra }, - { kItemPan, kTrackInfoSliderHeight, kTrackInfoSliderExtra }, + { kItemGain, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, + { kItemPan, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, STATUS_ITEMS - { 0, 0, 0 } + { 0, 0, 0, nullptr } }; -const TCPLine noteTrackTCPLines[] = { +const TrackInfo::TCPLine noteTrackTCPLines[] = { COMMON_ITEMS #ifdef EXPERIMENTAL_MIDI_OUT MUTE_SOLO_ITEMS(0) - { kItemMidiControlsRect, kMidiCellHeight * 4, 0 }, - { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra }, + { kItemMidiControlsRect, kMidiCellHeight * 4, 0, nullptr }, + { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, #endif - { 0, 0, 0 } + { 0, 0, 0, nullptr } }; -int totalTCPLines( const TCPLine *pLines, bool omitLastExtra ) +int totalTCPLines( const TrackInfo::TCPLine *pLines, bool omitLastExtra ) { int total = 0; int lastExtra = 0; @@ -5128,7 +5138,7 @@ int totalTCPLines( const TCPLine *pLines, bool omitLastExtra ) return total; } -const TCPLine *getTCPLines( const Track &track ) +const TrackInfo::TCPLine *getTCPLines( const Track &track ) { #ifdef USE_MIDI if ( track.GetKind() == Track::Note ) @@ -5142,7 +5152,7 @@ const TCPLine *getTCPLines( const Track &track ) } // return y value and height -std::pair< int, int > CalcItemY( const TCPLine *pLines, unsigned iItem ) +std::pair< int, int > CalcItemY( const TrackInfo::TCPLine *pLines, unsigned iItem ) { int y = 0; while ( pLines->items && @@ -5155,16 +5165,16 @@ std::pair< int, int > CalcItemY( const TCPLine *pLines, unsigned iItem ) // Items for the bottom of the panel, listed bottom-upwards // As also with the top items, the extra space is below the item -const TCPLine commonTrackTCPBottomLines[] = { +const TrackInfo::TCPLine commonTrackTCPBottomLines[] = { // The '0' avoids impinging on bottom line of TCP // Use -1 if you do want to do so. - { kItemSyncLock | kItemMinimize, kTrackInfoBtnSize, 0 }, - { 0, 0, 0 } + { kItemSyncLock | kItemMinimize, kTrackInfoBtnSize, 0, nullptr }, + { 0, 0, 0, nullptr } }; // return y value and height std::pair< int, int > CalcBottomItemY - ( const TCPLine *pLines, unsigned iItem, int height ) + ( const TrackInfo::TCPLine *pLines, unsigned iItem, int height ) { int y = height; while ( pLines->items && @@ -7250,10 +7260,56 @@ void TrackPanel::DrawZooming(wxDC * dc, const wxRect & clip) dc->DrawRectangle(rect); } +void TrackInfo::DrawItems +( wxDC *dc, const wxRect &rect, const Track &track, + int mouseCapture, bool captured ) +{ + const auto topLines = getTCPLines( track ); + const auto bottomLines = commonTrackTCPBottomLines; + DrawItems + ( dc, rect, &track, topLines, bottomLines, mouseCapture, captured ); +} + +void TrackInfo::DrawItems +( wxDC *dc, const wxRect &rect, const Track *pTrack, + const TCPLine topLines[], const TCPLine bottomLines[], + int mouseCapture, bool captured ) +{ + TrackInfo::SetTrackInfoFont(dc); + dc->SetTextForeground(theTheme.Colour(clrTrackPanelText)); + + { + const auto table = topLines; + int yy = 0; + for ( auto line = table; line->items; ++line ) { + wxRect itemRect{ + rect.x, rect.y + yy, + rect.width, line->height + }; + if ( !TrackInfo::HideTopItem( rect, itemRect ) && + line->drawFunction ) + line->drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); + yy += line->height + line->extraSpace; + } + } + { + const auto table = bottomLines; + int yy = rect.height; + for ( auto line = table; line->items; ++line ) { + yy -= line->height + line->extraSpace; + if ( line->drawFunction ) { + wxRect itemRect{ + rect.x, rect.y + yy, + rect.width, line->height + }; + line->drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); + } + } + } +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { - mTrackInfo.SetTrackInfoFont(dc); - dc->SetTextForeground(theTheme.Colour(clrTrackPanelText)); bool bIsWave = (t->GetKind() == Track::Wave); #ifdef USE_MIDI bool bIsNote = (t->GetKind() == Track::Note); @@ -7301,6 +7357,8 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) mTrackInfo.DrawMinimize(dc, rect, t, (captured && mMouseCapture==IsMinimizing)); + TrackInfo::DrawItems( dc, rect, *t, mMouseCapture, captured ); + // Draw the sync-lock indicator if this track is in a sync-lock selected group. if (t->IsSyncLockSelected()) { @@ -9385,7 +9443,7 @@ void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool cap #endif namespace { -unsigned DefaultTrackHeight( const TCPLine topLines[] ) +unsigned DefaultTrackHeight( const TrackInfo::TCPLine topLines[] ) { int needed = kTopMargin + kBottomMargin + diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 9fc547ec9..80716d521 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -76,6 +76,7 @@ enum { kTimerInterval = 50, // milliseconds }; + class AUDACITY_DLL_API TrackInfo { public: @@ -83,6 +84,17 @@ public: ~TrackInfo(); void ReCreateSliders(); + struct TCPLine; + + static void DrawItems + ( wxDC *dc, const wxRect &rect, const Track &track, int mouseCapture, + bool captured ); + + static void DrawItems + ( wxDC *dc, const wxRect &rect, const Track *pTrack, + const TCPLine topLines[], const TCPLine bottomLines[], + int mouseCapture, bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); From b4e38c28384043dd64cc844dda72476867088dec Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 13:23:00 -0400 Subject: [PATCH 07/13] Table includes draw function for Close and Title --- src/TrackPanel.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++-- src/TrackPanel.h | 6 +++ 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 87e578a60..4432c50bb 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5077,7 +5077,8 @@ enum : unsigned { #ifdef EXPERIMENTAL_DA #define TITLE_ITEMS \ - { kItemBarButtons, kTrackInfoBtnSize, 4, nullptr }, + { kItemBarButtons, kTrackInfoBtnSize, 4, \ + &TrackInfo::CloseTitleDrawFunction }, // DA: Has Mute and Solo on separate lines. #define MUTE_SOLO_ITEMS(extra) \ { kItemMute, kTrackInfoBtnSize + 1, 1, nullptr }, \ @@ -5088,7 +5089,8 @@ enum : unsigned { #else #define TITLE_ITEMS \ - { kItemBarButtons, kTrackInfoBtnSize, 0, nullptr }, + { kItemBarButtons, kTrackInfoBtnSize, 0, \ + &TrackInfo::CloseTitleDrawFunction }, #define MUTE_SOLO_ITEMS(extra) \ { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra, nullptr }, #define STATUS_ITEMS \ @@ -7308,6 +7310,92 @@ void TrackInfo::DrawItems } } +void TrackInfo::CloseTitleDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) +{ + bool selected = pTrack ? pTrack->GetSelected() : true; + { + bool down = captured && (pressed == TrackPanel::IsClosing); + wxRect bev = rect; + GetCloseBoxHorizontalBounds( rect, bev ); + AColor::Bevel2(*dc, !down, bev, selected ); + +#ifdef EXPERIMENTAL_THEMING + wxPen pen( theTheme.Colour( clrTrackPanelText )); + dc->SetPen( pen ); +#else + dc->SetPen(*wxBLACK_PEN); +#endif + bev.Inflate( -1, -1 ); + // Draw the "X" + const int s = 6; + + int ls = bev.x + ((bev.width - s) / 2); + int ts = bev.y + ((bev.height - s) / 2); + int rs = ls + s; + int bs = ts + s; + + AColor::Line(*dc, ls, ts, rs, bs); + AColor::Line(*dc, ls + 1, ts, rs + 1, bs); + AColor::Line(*dc, rs, ts, ls, bs); + AColor::Line(*dc, rs + 1, ts, ls + 1, bs); + + // bev.Inflate(-1, -1); + } + + { + wxString titleStr = + pTrack ? pTrack->GetName() : _("Name"); + + bool down = captured && (pressed == TrackPanel::IsPopping); + wxRect bev = rect; + GetTitleBarHorizontalBounds( rect, bev ); + //bev.Inflate(-1, -1); + AColor::Bevel2(*dc, !down, bev, selected); + + // Draw title text + SetTrackInfoFont(dc); + int allowableWidth = rect.width - 42; + + wxCoord textWidth, textHeight; + dc->GetTextExtent(titleStr, &textWidth, &textHeight); + while (textWidth > allowableWidth) { + titleStr = titleStr.Left(titleStr.Length() - 1); + dc->GetTextExtent(titleStr, &textWidth, &textHeight); + } + + // Pop-up triangle + #ifdef EXPERIMENTAL_THEMING + wxColour c = theTheme.Colour( clrTrackPanelText ); + #else + wxColour c = *wxBLACK; + #endif + + // wxGTK leaves little scraps (antialiasing?) of the + // characters if they are repeatedly drawn. This + // happens when holding down mouse button and moving + // in and out of the title bar. So clear it first. + // AColor::MediumTrackInfo(dc, t->GetSelected()); + // dc->DrawRectangle(bev); + + dc->SetTextForeground( c ); + dc->SetTextBackground( wxTRANSPARENT ); + dc->DrawText(titleStr, bev.x + 2, bev.y + (bev.height - textHeight) / 2); + + + + dc->SetPen(c); + dc->SetBrush(c); + + int s = 10; // Width of dropdown arrow...height is half of width + AColor::Arrow(*dc, + bev.GetRight() - s - 3, // 3 to offset from right border + bev.y + ((bev.height - (s / 2)) / 2), + s); + + } +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); @@ -7352,8 +7440,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) rect.height -= (kBottomMargin + kTopMargin); bool captured = (t == mCapturedTrack); - mTrackInfo.DrawCloseBox(dc, rect, t, (captured && mMouseCapture==IsClosing)); - mTrackInfo.DrawTitleBar(dc, rect, t, (captured && mMouseCapture==IsPopping)); mTrackInfo.DrawMinimize(dc, rect, t, (captured && mMouseCapture==IsMinimizing)); diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 80716d521..a6a2c5591 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -95,6 +95,10 @@ public: const TCPLine topLines[], const TCPLine bottomLines[], int mouseCapture, bool captured ); + static void CloseTitleDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); @@ -809,6 +813,7 @@ protected: int mInitialUpperActualHeight; bool mAutoScrolling; +public: enum MouseCaptureEnum { IsUncaptured=0, // This is the normal state for the mouse @@ -838,6 +843,7 @@ protected: }; +protected: enum MouseCaptureEnum mMouseCapture; virtual void SetCapturedTrack( Track * t, enum MouseCaptureEnum MouseCapture=IsUncaptured ); From 86763341afcd8519cd7fba8d2717e0722c61186f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 15:17:26 -0400 Subject: [PATCH 08/13] Table includes draw function for Minimize and Sync-lock icon --- src/TrackPanel.cpp | 65 ++++++++++++++++++++++++++++++++++------------ src/TrackPanel.h | 4 +++ 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 4432c50bb..31ab6274e 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5170,7 +5170,8 @@ std::pair< int, int > CalcItemY( const TrackInfo::TCPLine *pLines, unsigned iIte const TrackInfo::TCPLine commonTrackTCPBottomLines[] = { // The '0' avoids impinging on bottom line of TCP // Use -1 if you do want to do so. - { kItemSyncLock | kItemMinimize, kTrackInfoBtnSize, 0, nullptr }, + { kItemSyncLock | kItemMinimize, kTrackInfoBtnSize, 0, + &TrackInfo::MinimizeSyncLockDrawFunction }, { 0, 0, 0, nullptr } }; @@ -7396,6 +7397,53 @@ void TrackInfo::CloseTitleDrawFunction } } +void TrackInfo::MinimizeSyncLockDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) +{ + bool selected = pTrack ? pTrack->GetSelected() : true; + bool syncLockSelected = pTrack ? pTrack->IsSyncLockSelected() : true; + bool minimized = pTrack ? pTrack->GetMinimized() : false; + { + bool down = captured && (pressed == TrackPanel::IsMinimizing); + wxRect bev = rect; + GetMinimizeHorizontalBounds(rect, bev); + + // Clear background to get rid of previous arrow + //AColor::MediumTrackInfo(dc, t->GetSelected()); + //dc->DrawRectangle(bev); + + AColor::Bevel2(*dc, !down, bev, selected); + +#ifdef EXPERIMENTAL_THEMING + wxColour c = theTheme.Colour(clrTrackPanelText); + dc->SetBrush(c); + dc->SetPen(c); +#else + AColor::Dark(dc, selected); +#endif + + AColor::Arrow(*dc, + bev.x - 5 + bev.width / 2, + bev.y - 2 + bev.height / 2, + 10, + minimized); + } + + // Draw the sync-lock indicator if this track is in a sync-lock selected group. + if (syncLockSelected) + { + wxRect syncLockIconRect = rect; + + GetSyncLockHorizontalBounds( rect, syncLockIconRect ); + wxBitmap syncLockBitmap(theTheme.Image(bmpSyncLockIcon)); + // Icon is 12x12 and syncLockIconRect is 16x16. + dc->DrawBitmap(syncLockBitmap, + syncLockIconRect.x + 3, + syncLockIconRect.y + 2, + true); + } +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); @@ -7441,23 +7489,8 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) bool captured = (t == mCapturedTrack); - mTrackInfo.DrawMinimize(dc, rect, t, (captured && mMouseCapture==IsMinimizing)); - TrackInfo::DrawItems( dc, rect, *t, mMouseCapture, captured ); - // Draw the sync-lock indicator if this track is in a sync-lock selected group. - if (t->IsSyncLockSelected()) - { - wxRect syncLockIconRect; - mTrackInfo.GetSyncLockIconRect(rect, syncLockIconRect); - wxBitmap syncLockBitmap(theTheme.Image(bmpSyncLockIcon)); - // Icon is 12x12 and syncLockIconRect is 16x16. - dc->DrawBitmap(syncLockBitmap, - syncLockIconRect.x + 3, - syncLockIconRect.y + 2, - true); - } - //mTrackInfo.DrawBordersWithin( dc, rect, *t ); auto wt = bIsWave ? static_cast(t) : nullptr; diff --git a/src/TrackPanel.h b/src/TrackPanel.h index a6a2c5591..0f06c024c 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -99,6 +99,10 @@ public: ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ); + static void MinimizeSyncLockDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); From 329aa8393e46ca338048294a37ea7cf2f11253b1 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 15:51:06 -0400 Subject: [PATCH 09/13] Table includes draw function for Midi controls --- src/NoteTrack.cpp | 6 ++++-- src/NoteTrack.h | 3 ++- src/TrackPanel.cpp | 19 +++++++++++++------ src/TrackPanel.h | 4 ++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index ac5cf8129..d0e90ef45 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -250,7 +250,8 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1, // Draws the midi channel toggle buttons within the given rect. // The rect should be evenly divisible by 4 on both axis. -void NoteTrack::DrawLabelControls(wxDC & dc, const wxRect &rect) +void NoteTrack::DrawLabelControls +( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect ) { wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4"); wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4"); @@ -270,7 +271,8 @@ void NoteTrack::DrawLabelControls(wxDC & dc, const wxRect &rect) box.width = cellWidth; box.height = cellHeight; - if (IsVisibleChan(chanName - 1)) { + bool visible = pTrack ? pTrack->IsVisibleChan(chanName - 1) : true; + if (visible) { AColor::MIDIChannel(&dc, chanName); dc.DrawRectangle(box); // two choices: channel is enabled (to see and play) when button is in diff --git a/src/NoteTrack.h b/src/NoteTrack.h index c0c11ab34..76dd92410 100644 --- a/src/NoteTrack.h +++ b/src/NoteTrack.h @@ -82,7 +82,8 @@ class AUDACITY_DLL_API NoteTrack final void WarpAndTransposeNotes(double t0, double t1, const TimeWarper &warper, double semitones); - void DrawLabelControls(wxDC & dc, const wxRect &rect); + static void DrawLabelControls + ( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect ); bool LabelClick(const wxRect &rect, int x, int y, bool right); void SetSequence(std::unique_ptr &&seq); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 31ab6274e..a6ca56a92 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5120,7 +5120,8 @@ const TrackInfo::TCPLine noteTrackTCPLines[] = { COMMON_ITEMS #ifdef EXPERIMENTAL_MIDI_OUT MUTE_SOLO_ITEMS(0) - { kItemMidiControlsRect, kMidiCellHeight * 4, 0, nullptr }, + { kItemMidiControlsRect, kMidiCellHeight * 4, 0, + &TrackInfo::MidiControlsDrawFunction }, { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, #endif { 0, 0, 0, nullptr } @@ -7444,6 +7445,17 @@ void TrackInfo::MinimizeSyncLockDrawFunction } } +void TrackInfo::MidiControlsDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) +{ +#ifdef EXPERIMENTAL_MIDI_OUT + wxRect midiRect = rect; + GetMidiControlsHorizontalBounds(rect, midiRect); + NoteTrack::DrawLabelControls + ( static_cast(pTrack), *dc, midiRect ); +#endif // EXPERIMENTAL_MIDI_OUT +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); @@ -7528,11 +7540,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) #ifdef EXPERIMENTAL_MIDI_OUT else if (bIsNote) { - wxRect midiRect; - mTrackInfo.GetMidiControlsRect(rect, midiRect); - - if ( !TrackInfo::HideTopItem( rect, midiRect ) ) - static_cast(t)->DrawLabelControls(*dc, midiRect); mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsMuting), false, HasSoloButton()); mTrackInfo.DrawMuteSolo(dc, rect, t, diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 0f06c024c..0641b7256 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -103,6 +103,10 @@ public: ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ); + static void MidiControlsDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); From 4df84f126e1f6ad0cd2697dd1e3fbdc17094d26c Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 12 Jun 2017 16:10:03 -0400 Subject: [PATCH 10/13] Table includes draw functions for sliders --- src/TrackPanel.cpp | 81 +++++++++++++++++++++++++--------------------- src/TrackPanel.h | 25 +++++++++++--- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index a6ca56a92..45f8a1778 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5110,8 +5110,10 @@ const TrackInfo::TCPLine commonTrackTCPLines[] = { const TrackInfo::TCPLine waveTrackTCPLines[] = { COMMON_ITEMS MUTE_SOLO_ITEMS(2) - { kItemGain, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, - { kItemPan, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, + { kItemGain, kTrackInfoSliderHeight, kTrackInfoSliderExtra, + &TrackInfo::GainSliderDrawFunction }, + { kItemPan, kTrackInfoSliderHeight, kTrackInfoSliderExtra, + &TrackInfo::PanSliderDrawFunction }, STATUS_ITEMS { 0, 0, 0, nullptr } }; @@ -5122,7 +5124,8 @@ const TrackInfo::TCPLine noteTrackTCPLines[] = { MUTE_SOLO_ITEMS(0) { kItemMidiControlsRect, kMidiCellHeight * 4, 0, &TrackInfo::MidiControlsDrawFunction }, - { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra, nullptr }, + { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra, + &TrackInfo::VelocitySliderDrawFunction }, #endif { 0, 0, 0, nullptr } }; @@ -7456,6 +7459,41 @@ void TrackInfo::MidiControlsDrawFunction #endif // EXPERIMENTAL_MIDI_OUT } +template +void TrackInfo::SliderDrawFunction +( LWSlider *(*Selector) + (const wxRect &sliderRect, const TrackClass *t, bool captured, wxWindow*), + wxDC *dc, const wxRect &rect, const Track *pTrack, bool captured ) +{ + wxRect sliderRect = rect; + TrackInfo::GetSliderHorizontalBounds( rect.GetTopLeft(), sliderRect ); + auto wt = static_cast( pTrack ); + Selector( sliderRect, wt, captured, nullptr )->OnPaint(*dc); +} + +void TrackInfo::PanSliderDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) +{ + SliderDrawFunction + ( &TrackInfo::PanSlider, dc, rect, pTrack, captured); +} + +void TrackInfo::GainSliderDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) +{ + SliderDrawFunction + ( &TrackInfo::GainSlider, dc, rect, pTrack, captured); +} + +#ifdef EXPERIMENTAL_MIDI_OUT +void TrackInfo::VelocitySliderDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) +{ + SliderDrawFunction + ( &TrackInfo::VelocitySlider, dc, rect, pTrack, captured); +} +#endif + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); @@ -7510,8 +7548,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsMuting), false, HasSoloButton()); mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsSoloing), true, HasSoloButton()); - mTrackInfo.DrawSliders(dc, (WaveTrack *)t, rect, captured); - // DA: For classic Audacity, show stero/mono and rate. #ifndef EXPERIMENTAL_DA if (!t->GetMinimized()) { @@ -7544,10 +7580,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) (captured && mMouseCapture == IsMuting), false, HasSoloButton()); mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsSoloing), true, HasSoloButton()); - - // Place a volume control below channel buttons (this will - // control an offset to midi velocity). - mTrackInfo.DrawVelocitySlider(dc, static_cast(t), rect, captured); } #endif // EXPERIMENTAL_MIDI_OUT } @@ -9543,31 +9575,6 @@ void TrackInfo::DrawMinimize(wxDC * dc, const wxRect & rect, Track * t, bool dow } -void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect rect, bool captured) const -{ - wxRect sliderRect; - - GetGainRect(rect.GetTopLeft(), sliderRect); - if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) - GainSlider(sliderRect, t, captured, pParent)->OnPaint(*dc); - - GetPanRect(rect.GetTopLeft(), sliderRect); - if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) - PanSlider(sliderRect, t, captured, pParent)->OnPaint(*dc); -} - -#ifdef EXPERIMENTAL_MIDI_OUT -void TrackInfo::DrawVelocitySlider(wxDC *dc, NoteTrack *t, wxRect rect, bool captured) const -{ - wxRect sliderRect; - - GetVelocityRect( rect.GetTopLeft(), sliderRect ); - if ( !TrackInfo::HideTopItem( rect, sliderRect, kTrackInfoSliderAllowance ) ) { - VelocitySlider(sliderRect, t, captured, pParent)->OnPaint(*dc); - } -} -#endif - namespace { unsigned DefaultTrackHeight( const TrackInfo::TCPLine topLines[] ) { @@ -9604,7 +9611,7 @@ LWSlider * TrackInfo::GainSlider (const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent) { wxPoint pos = sliderRect.GetPosition(); - float gain = t->GetGain(); + float gain = t ? t->GetGain() : 1.0; gGain->Move(pos); gGain->Set(gain); @@ -9620,7 +9627,7 @@ LWSlider * TrackInfo::PanSlider (const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent) { wxPoint pos = sliderRect.GetPosition(); - float pan = t->GetPan(); + float pan = t ? t->GetPan() : 0.0; gPan->Move(pos); gPan->Set(pan); @@ -9637,7 +9644,7 @@ LWSlider * TrackInfo::VelocitySlider (const wxRect &sliderRect, const NoteTrack *t, bool captured, wxWindow *pParent) { wxPoint pos = sliderRect.GetPosition(); - float velocity = t->GetVelocity(); + float velocity = t ? t->GetVelocity() : 0.0; gVelocity->Move(pos); gVelocity->Set(velocity); diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 0641b7256..807a1210f 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -107,6 +107,27 @@ public: ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ); + template + static void SliderDrawFunction + ( LWSlider *(*Selector) + (const wxRect &sliderRect, const TrackClass *t, bool captured, + wxWindow*), + wxDC *dc, const wxRect &rect, const Track *pTrack, bool captured ); + + static void PanSliderDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + + static void GainSliderDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + +#ifdef EXPERIMENTAL_MIDI_OUT + static void VelocitySliderDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); +#endif + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); @@ -118,10 +139,6 @@ 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; - 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; From ce77f176b506b44c25962378e66f745834db9370 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 13 Jun 2017 08:02:44 -0400 Subject: [PATCH 11/13] Table includes draw functions for Mute and Solo --- src/TrackPanel.cpp | 110 ++++++++++++++++++++++++++++++++++++++------- src/TrackPanel.h | 16 +++++++ 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 45f8a1778..6dcd18feb 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5081,8 +5081,10 @@ enum : unsigned { &TrackInfo::CloseTitleDrawFunction }, // DA: Has Mute and Solo on separate lines. #define MUTE_SOLO_ITEMS(extra) \ - { kItemMute, kTrackInfoBtnSize + 1, 1, nullptr }, \ - { kItemSolo, kTrackInfoBtnSize + 1, extra, nullptr }, + { kItemMute, kTrackInfoBtnSize + 1, 1, \ + &TrackInfo::WideMuteDrawFunction }, \ + { kItemSolo, kTrackInfoBtnSize + 1, extra, \ + &TrackInfo::WideSoloDrawFunction }, // DA: Does not have status information for a track. #define STATUS_ITEMS @@ -5092,7 +5094,8 @@ enum : unsigned { { kItemBarButtons, kTrackInfoBtnSize, 0, \ &TrackInfo::CloseTitleDrawFunction }, #define MUTE_SOLO_ITEMS(extra) \ - { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra, nullptr }, + { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra, \ + &TrackInfo::MuteAndSoloDrawFunction }, #define STATUS_ITEMS \ { kItemStatusInfo1, 12, 0, nullptr }, \ { kItemStatusInfo2, 12, 0, nullptr }, @@ -7494,12 +7497,96 @@ void TrackInfo::VelocitySliderDrawFunction } #endif +void TrackInfo::MuteOrSoloDrawFunction +( wxDC *dc, const wxRect &bev, const Track *pTrack, int pressed, bool captured, + bool solo ) +{ + bool down = captured && + (pressed == ( solo ? TrackPanel::IsSoloing : TrackPanel::IsMuting )); + //bev.Inflate(-1, -1); + bool selected = pTrack ? pTrack->GetSelected() : true; + auto pt = dynamic_cast(pTrack); + bool value = pt ? (solo ? pt->GetSolo() : pt->GetMute()) : false; + +#if 0 + AColor::MediumTrackInfo( dc, t->GetSelected()); + if( solo ) + { + if( pt && pt->GetSolo() ) + { + AColor::Solo(dc, pt->GetSolo(), t->GetSelected()); + } + } + else + { + if( pt && pt->GetMute() ) + { + AColor::Mute(dc, pt->GetMute(), t->GetSelected(), pt->GetSolo()); + } + } + //(solo) ? AColor::Solo(dc, t->GetSolo(), t->GetSelected()) : + // AColor::Mute(dc, t->GetMute(), t->GetSelected(), t->GetSolo()); + dc->SetPen( *wxTRANSPARENT_PEN );//No border! + dc->DrawRectangle(bev); +#endif + + wxCoord textWidth, textHeight; + wxString str = (solo) ? + /* i18n-hint: This is on a button that will silence all the other tracks.*/ + _("Solo") : + /* i18n-hint: This is on a button that will silence this track.*/ + _("Mute"); + + AColor::Bevel2( + *dc, + value == down, + bev, + selected + ); + + SetTrackInfoFont(dc); + dc->GetTextExtent(str, &textWidth, &textHeight); + dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2); +} + +void TrackInfo::WideMuteDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) +{ + wxRect bev = rect; + GetWideMuteSoloHorizontalBounds( rect, bev ); + MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, false ); +} + +void TrackInfo::WideSoloDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) +{ + wxRect bev = rect; + GetWideMuteSoloHorizontalBounds( rect, bev ); + MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, true ); +} + +void TrackInfo::MuteAndSoloDrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) +{ + bool bHasSoloButton = TrackPanel::HasSoloButton(); + + wxRect bev = rect; + if ( bHasSoloButton ) + GetNarrowMuteHorizontalBounds( rect, bev ); + else + GetWideMuteSoloHorizontalBounds( rect, bev ); + MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, false ); + + if( !bHasSoloButton ) + return; + + GetNarrowSoloHorizontalBounds( rect, bev ); + MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, true ); +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); -#ifdef USE_MIDI - bool bIsNote = (t->GetKind() == Track::Note); -#endif // Draw things that extend right of track control panel { @@ -7545,8 +7632,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) auto wt = bIsWave ? static_cast(t) : nullptr; if (bIsWave) { - mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsMuting), false, HasSoloButton()); - mTrackInfo.DrawMuteSolo(dc, rect, t, (captured && mMouseCapture == IsSoloing), true, HasSoloButton()); // DA: For classic Audacity, show stero/mono and rate. #ifndef EXPERIMENTAL_DA @@ -7573,15 +7658,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) } #endif } - -#ifdef EXPERIMENTAL_MIDI_OUT - else if (bIsNote) { - mTrackInfo.DrawMuteSolo(dc, rect, t, - (captured && mMouseCapture == IsMuting), false, HasSoloButton()); - mTrackInfo.DrawMuteSolo(dc, rect, t, - (captured && mMouseCapture == IsSoloing), true, HasSoloButton()); - } -#endif // EXPERIMENTAL_MIDI_OUT } // Given rectangle should be the whole track rectangle diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 807a1210f..3a9574eb6 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -128,6 +128,22 @@ public: bool captured ); #endif + static void MuteOrSoloDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured, bool solo ); + + static void WideMuteDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + + static void WideSoloDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + + static void MuteAndSoloDrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); From 063c6c236f9951c5d1c4868b0791c57b6a440cd1 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 13 Jun 2017 09:14:58 -0400 Subject: [PATCH 12/13] Table includes draw functions for status items --- src/TrackPanel.cpp | 103 +++++++++++++++++++++------------------------ src/TrackPanel.h | 13 +++++- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 6dcd18feb..9f32ed73b 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5097,8 +5097,10 @@ enum : unsigned { { kItemMute | kItemSolo, kTrackInfoBtnSize + 1, extra, \ &TrackInfo::MuteAndSoloDrawFunction }, #define STATUS_ITEMS \ - { kItemStatusInfo1, 12, 0, nullptr }, \ - { kItemStatusInfo2, 12, 0, nullptr }, + { kItemStatusInfo1, 12, 0, \ + &TrackInfo::Status1DrawFunction }, \ + { kItemStatusInfo2, 12, 0, \ + &TrackInfo::Status2DrawFunction }, #endif @@ -7584,6 +7586,50 @@ void TrackInfo::MuteAndSoloDrawFunction MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, true ); } +void TrackInfo::StatusDrawFunction + ( const wxString &string, wxDC *dc, const wxRect &rect ) +{ + static const int offset = 3; + dc->DrawText(string, rect.x + offset, rect.y); +} + +void TrackInfo::Status1DrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) +{ + auto wt = static_cast(pTrack); + + /// Returns the string to be displayed in the track label + /// indicating whether the track is mono, left, right, or + /// stereo and what sample rate it's using. + auto rate = wt ? wt->GetRate() : 44100.0; + wxString s = wxString::Format(wxT("%dHz"), (int) (rate + 0.5)); + if (!wt || (wt->GetLinked() +#ifdef EXPERIMENTAL_OUTPUT_DISPLAY + && wt->GetChannel() != Track::MonoChannel +#endif + )) + s = _("Stereo, ") + s; + else { + if (wt->GetChannel() == Track::MonoChannel) + s = _("Mono, ") + s; + else if (wt->GetChannel() == Track::LeftChannel) + s = _("Left, ") + s; + else if (wt->GetChannel() == Track::RightChannel) + s = _("Right, ") + s; + } + + StatusDrawFunction( s, dc, rect ); +} + +void TrackInfo::Status2DrawFunction +( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) +{ + auto wt = static_cast(pTrack); + auto format = wt ? wt->GetSampleFormat() : floatSample; + auto s = GetSampleFormatStr(format); + StatusDrawFunction( s, dc, rect ); +} + void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) { bool bIsWave = (t->GetKind() == Track::Wave); @@ -7629,35 +7675,6 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) TrackInfo::DrawItems( dc, rect, *t, mMouseCapture, captured ); //mTrackInfo.DrawBordersWithin( dc, rect, *t ); - - auto wt = bIsWave ? static_cast(t) : nullptr; - if (bIsWave) { - -// DA: For classic Audacity, show stero/mono and rate. -#ifndef EXPERIMENTAL_DA - if (!t->GetMinimized()) { - - int offset = 3; - auto pair = CalcItemY( waveTrackTCPLines, kItemStatusInfo1 ); - wxRect textRect { - rect.x + offset, rect.y + pair.first, - rect.width, pair.second - }; - if ( !TrackInfo::HideTopItem( rect, textRect ) ) - dc->DrawText(TrackSubText(wt), - textRect.x, textRect.y); - - pair = CalcItemY( waveTrackTCPLines, kItemStatusInfo2 ); - textRect = { - rect.x + offset, rect.y + pair.first, - rect.width, pair.second - }; - if ( !TrackInfo::HideTopItem( rect, textRect ) ) - dc->DrawText(GetSampleFormatStr(((WaveTrack *) t)->GetSampleFormat()), - textRect.x, textRect.y ); - } -#endif - } } // Given rectangle should be the whole track rectangle @@ -8109,30 +8126,6 @@ void TrackPanel::DrawShadow(Track * /* t */ , wxDC * dc, const wxRect & rect) AColor::Line(*dc, right, rect.y, right, rect.y + 1); } -/// Returns the string to be displayed in the track label -/// indicating whether the track is mono, left, right, or -/// stereo and what sample rate it's using. -wxString TrackPanel::TrackSubText(WaveTrack * t) -{ - wxString s = wxString::Format(wxT("%dHz"), (int) (t->GetRate() + 0.5)); - if (t->GetLinked() -#ifdef EXPERIMENTAL_OUTPUT_DISPLAY - && t->GetChannel() != Track::MonoChannel -#endif - ) - s = _("Stereo, ") + s; - else { - if (t->GetChannel() == Track::MonoChannel) - s = _("Mono, ") + s; - else if (t->GetChannel() == Track::LeftChannel) - s = _("Left, ") + s; - else if (t->GetChannel() == Track::RightChannel) - s = _("Right, ") + s; - } - - return s; -} - /// Handle the menu options that change a track between /// left channel, right channel, and mono. static int channels[] = { Track::LeftChannel, Track::RightChannel, diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 3a9574eb6..12900ecd6 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -144,6 +144,17 @@ public: ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ); + static void StatusDrawFunction + ( const wxString &string, wxDC *dc, const wxRect &rect ); + + static void Status1DrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + + static void Status2DrawFunction + ( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, + bool captured ); + private: int GetTrackInfoWidth() const; static void SetTrackInfoFont(wxDC *dc); @@ -679,8 +690,6 @@ protected: int mLabelTrackStartXPos; int mLabelTrackStartYPos; - virtual wxString TrackSubText(WaveTrack *t); - TrackInfo mTrackInfo; public: From 5982dccd36d86592fd8073eea72715de310d729b Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 13 Jun 2017 13:34:12 -0400 Subject: [PATCH 13/13] Redo layout tables as std::vector --- src/TrackPanel.cpp | 75 +++++++++++++++++++++++++--------------------- src/TrackPanel.h | 3 +- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 9f32ed73b..fe84bc170 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -5056,6 +5056,9 @@ struct TrackInfo::TCPLine { namespace { +#define RANGE(array) (array), (array) + sizeof(array)/sizeof(*(array)) +using TCPLines = std::vector< TrackInfo::TCPLine >; + enum : unsigned { // The sequence is not significant, just keep bits distinct kItemBarButtons = 1 << 0, @@ -5107,12 +5110,12 @@ enum : unsigned { #define COMMON_ITEMS \ TITLE_ITEMS -const TrackInfo::TCPLine commonTrackTCPLines[] = { +const TrackInfo::TCPLine defaultCommonTrackTCPLines[] = { COMMON_ITEMS - { 0, 0, 0, nullptr } }; +TCPLines commonTrackTCPLines{ RANGE(defaultCommonTrackTCPLines) }; -const TrackInfo::TCPLine waveTrackTCPLines[] = { +const TrackInfo::TCPLine defaultWaveTrackTCPLines[] = { COMMON_ITEMS MUTE_SOLO_ITEMS(2) { kItemGain, kTrackInfoSliderHeight, kTrackInfoSliderExtra, @@ -5120,10 +5123,10 @@ const TrackInfo::TCPLine waveTrackTCPLines[] = { { kItemPan, kTrackInfoSliderHeight, kTrackInfoSliderExtra, &TrackInfo::PanSliderDrawFunction }, STATUS_ITEMS - { 0, 0, 0, nullptr } }; +TCPLines waveTrackTCPLines{ RANGE(defaultWaveTrackTCPLines) }; -const TrackInfo::TCPLine noteTrackTCPLines[] = { +const TrackInfo::TCPLine defaultNoteTrackTCPLines[] = { COMMON_ITEMS #ifdef EXPERIMENTAL_MIDI_OUT MUTE_SOLO_ITEMS(0) @@ -5132,24 +5135,23 @@ const TrackInfo::TCPLine noteTrackTCPLines[] = { { kItemVelocity, kTrackInfoSliderHeight, kTrackInfoSliderExtra, &TrackInfo::VelocitySliderDrawFunction }, #endif - { 0, 0, 0, nullptr } }; +TCPLines noteTrackTCPLines{ RANGE(defaultNoteTrackTCPLines) }; -int totalTCPLines( const TrackInfo::TCPLine *pLines, bool omitLastExtra ) +int totalTCPLines( const TCPLines &lines, bool omitLastExtra ) { int total = 0; int lastExtra = 0; - while ( pLines->items ) { - lastExtra = pLines->extraSpace; - total += pLines->height + lastExtra; - ++pLines; + for ( const auto line : lines ) { + lastExtra = line.extraSpace; + total += line.height + lastExtra; } if (omitLastExtra) total -= lastExtra; return total; } -const TrackInfo::TCPLine *getTCPLines( const Track &track ) +const TCPLines &getTCPLines( const Track &track ) { #ifdef USE_MIDI if ( track.GetKind() == Track::Note ) @@ -5163,38 +5165,45 @@ const TrackInfo::TCPLine *getTCPLines( const Track &track ) } // return y value and height -std::pair< int, int > CalcItemY( const TrackInfo::TCPLine *pLines, unsigned iItem ) +std::pair< int, int > CalcItemY( const TCPLines &lines, unsigned iItem ) { int y = 0; - while ( pLines->items && + auto pLines = lines.begin(); + while ( pLines != lines.end() && 0 == (pLines->items & iItem) ) { y += pLines->height + pLines->extraSpace; ++pLines; } - return { y, pLines->height }; + int height = 0; + if ( pLines != lines.end() ) + height = pLines->height; + return { y, height }; } // Items for the bottom of the panel, listed bottom-upwards // As also with the top items, the extra space is below the item -const TrackInfo::TCPLine commonTrackTCPBottomLines[] = { +const TrackInfo::TCPLine defaultCommonTrackTCPBottomLines[] = { // The '0' avoids impinging on bottom line of TCP // Use -1 if you do want to do so. { kItemSyncLock | kItemMinimize, kTrackInfoBtnSize, 0, &TrackInfo::MinimizeSyncLockDrawFunction }, - { 0, 0, 0, nullptr } }; +TCPLines commonTrackTCPBottomLines{ RANGE(defaultCommonTrackTCPBottomLines) }; // return y value and height std::pair< int, int > CalcBottomItemY - ( const TrackInfo::TCPLine *pLines, unsigned iItem, int height ) + ( const TCPLines &lines, unsigned iItem, int height ) { int y = height; - while ( pLines->items && + auto pLines = lines.begin(); + while ( pLines != lines.end() && 0 == (pLines->items & iItem) ) { y -= pLines->height + pLines->extraSpace; ++pLines; } - return { y - (pLines->height + pLines->extraSpace ), pLines->height }; + if (pLines != lines.end()) + y -= (pLines->height + pLines->extraSpace ); + return { y, pLines->height }; } } @@ -7284,37 +7293,35 @@ void TrackInfo::DrawItems void TrackInfo::DrawItems ( wxDC *dc, const wxRect &rect, const Track *pTrack, - const TCPLine topLines[], const TCPLine bottomLines[], + const std::vector &topLines, const std::vector &bottomLines, int mouseCapture, bool captured ) { TrackInfo::SetTrackInfoFont(dc); dc->SetTextForeground(theTheme.Colour(clrTrackPanelText)); { - const auto table = topLines; int yy = 0; - for ( auto line = table; line->items; ++line ) { + for ( const auto &line : topLines ) { wxRect itemRect{ rect.x, rect.y + yy, - rect.width, line->height + rect.width, line.height }; if ( !TrackInfo::HideTopItem( rect, itemRect ) && - line->drawFunction ) - line->drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); - yy += line->height + line->extraSpace; + line.drawFunction ) + line.drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); + yy += line.height + line.extraSpace; } } { - const auto table = bottomLines; int yy = rect.height; - for ( auto line = table; line->items; ++line ) { - yy -= line->height + line->extraSpace; - if ( line->drawFunction ) { + for ( const auto &line : bottomLines ) { + yy -= line.height + line.extraSpace; + if ( line.drawFunction ) { wxRect itemRect{ rect.x, rect.y + yy, - rect.width, line->height + rect.width, line.height }; - line->drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); + line.drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); } } } @@ -9645,7 +9652,7 @@ void TrackInfo::DrawMinimize(wxDC * dc, const wxRect & rect, Track * t, bool dow } namespace { -unsigned DefaultTrackHeight( const TrackInfo::TCPLine topLines[] ) +unsigned DefaultTrackHeight( const TCPLines &topLines ) { int needed = kTopMargin + kBottomMargin + diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 12900ecd6..ed7de67ee 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -92,7 +92,8 @@ public: static void DrawItems ( wxDC *dc, const wxRect &rect, const Track *pTrack, - const TCPLine topLines[], const TCPLine bottomLines[], + const std::vector &topLines, + const std::vector &bottomLines, int mouseCapture, bool captured ); static void CloseTitleDrawFunction