From 6a9dae20f538bf0fb1df0d5c822005250b87dd3c Mon Sep 17 00:00:00 2001 From: Leland Lucius Date: Sun, 23 Aug 2015 20:25:01 -0500 Subject: [PATCH] Appearance on OSX is now back to normal or better Some additional wx3 cleanup as well. --- mac/Build.txt | 6 +- .../wxMac_bug_2_10.5.8_PPC.patch | 14 - src/AColor.cpp | 8 +- src/AboutDialog.cpp | 7 +- src/AudacityApp.cpp | 10 - src/AudacityApp.h | 50 -- src/FileIO.cpp | 2 - src/LabelDialog.cpp | 4 - src/MixerBoard.cpp | 5 - src/Project.cpp | 2 +- src/Project.h | 4 +- src/ShuttleGui.cpp | 22 - src/ShuttleGui.h | 2 - src/Snap.cpp | 302 +++++++---- src/Snap.h | 93 ++-- src/Tags.cpp | 4 - src/Track.h | 2 + src/TrackArtist.cpp | 15 +- src/TrackPanel.cpp | 267 ++++----- src/TrackPanel.h | 8 +- src/effects/Effect.cpp | 38 -- src/effects/Effect.h | 8 - src/export/ExportPCM.cpp | 8 - src/import/ImportPCM.cpp | 6 +- src/prefs/PrefsDialog.cpp | 4 - src/toolbars/ControlToolBar.cpp | 5 - src/toolbars/DeviceToolBar.cpp | 5 - src/widgets/ASlider.cpp | 505 ++++++++++++------ src/widgets/ASlider.h | 5 +- src/widgets/KeyView.cpp | 73 +-- src/widgets/KeyView.h | 5 - src/widgets/Meter.cpp | 66 +-- src/widgets/Ruler.cpp | 218 ++++---- src/widgets/Ruler.h | 22 +- src/widgets/numformatter.cpp | 5 - 35 files changed, 876 insertions(+), 924 deletions(-) delete mode 100644 mac/wxMac_additions/wxMac_bug_2_10.5.8_PPC.patch diff --git a/mac/Build.txt b/mac/Build.txt index ffe9b30be..8aa27078f 100644 --- a/mac/Build.txt +++ b/mac/Build.txt @@ -27,9 +27,13 @@ Once downloaded untar it (your browser may have already done this): tar xf wxWidgets-3.0.2.tar.bz2 -And build/install it: +A couple of fixes need to be applied wxWidgets: cd wxWidgets-3.0.2 + patch -p0 -i /mac/wxMac_additions/wxMac-3.0.2-fixes.patch + +And finally build/install it: + sudo /mac/build_wxwidgets You should now be able to build Audacity using either the Xcode application or the diff --git a/mac/wxMac_additions/wxMac_bug_2_10.5.8_PPC.patch b/mac/wxMac_additions/wxMac_bug_2_10.5.8_PPC.patch deleted file mode 100644 index 8c3019f81..000000000 --- a/mac/wxMac_additions/wxMac_bug_2_10.5.8_PPC.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -wruN orig/wxMac-2.8.12/src/unix/utilsunx.cpp wxMac-2.8.12/src/unix/utilsunx.cpp ---- orig/wxMac-2.8.12/src/unix/utilsunx.cpp 2010-04-15 04:25:58.000000000 -0500 -+++ wxMac-2.8.12/src/unix/utilsunx.cpp 2011-03-30 00:07:28.000000000 -0500 -@@ -1202,8 +1202,8 @@ - wxMAC_MachPortEndProcessDetect helper function. Though in practice - this shouldn't be a problem since it wasn't prototyped anywhere. - */ --#define USE_OLD_DARWIN_END_PROCESS_DETECT (defined(__DARWIN__) && defined(__WXMAC__)) --// #define USE_OLD_DARWIN_END_PROCESS_DETECT 0 -+// #define USE_OLD_DARWIN_END_PROCESS_DETECT (defined(__DARWIN__) && defined(__WXMAC__)) -+#define USE_OLD_DARWIN_END_PROCESS_DETECT 0 - - // wxMac doesn't use the same process end detection mechanisms so we don't - // need wxExecute-related helpers for it. diff --git a/src/AColor.cpp b/src/AColor.cpp index 8993e85ce..2677318f3 100644 --- a/src/AColor.cpp +++ b/src/AColor.cpp @@ -105,7 +105,7 @@ void AColor::Line(wxDC & dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) // last point since it is now based on the new wxGraphicsContext system. // Make the other platforms do the same thing since the other platforms // "may" follow they get wxGraphicsContext going. -#if defined(__WXMAC__) +#if defined(__WXMAC__) || defined(__WXGTK__) dc.DrawLine(x1, y1, x2, y2); #else bool point = false; @@ -301,13 +301,17 @@ void AColor::TrackPanelBackground(wxDC * dc, bool selected) #endif } - void AColor::CursorColor(wxDC * dc) { if (!inited) Init(); +#if defined(__WXMAC__) || defined(__WXGTK__) + dc->SetLogicalFunction(wxCOPY); + dc->SetPen(wxColor(0, 0, 0, 128)); +#else dc->SetLogicalFunction(wxINVERT); dc->SetPen(cursorPen); +#endif } void AColor::IndicatorColor(wxDC * dc, bool bIsNotRecording) diff --git a/src/AboutDialog.cpp b/src/AboutDialog.cpp index 4a93260ff..52ca7f542 100644 --- a/src/AboutDialog.cpp +++ b/src/AboutDialog.cpp @@ -433,11 +433,8 @@ void AboutDialog::PopulateInformationPage( ShuttleGui & S ) AddBuildinfoRow(&informationStr, wxT("PortAudio"), _("Audio playback and recording"), wxString(wxT("v19"))); - informationStr += wxT(""); // start new row - // wxWidgets version: - informationStr += wxVERSION_STRING; - informationStr += wxT(""); - informationStr += wxT("\n"); // end of row + AddBuildinfoRow(&informationStr, wxT("wxWidgets"), + _("Cross-platform GUI library"), wxVERSION_NUM_DOT_STRING_T); informationStr += wxT("\n"); //end table of libraries informationStr += wxT("

"); diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index f528219b7..c83f7101f 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -615,16 +615,6 @@ public: return true; } - -#if !wxCHECK_VERSION(3, 0, 0) - bool OnExecute(const wxString & topic, - wxChar *data, - int WXUNUSED(size), - wxIPCFormat WXUNUSED(format)) - { - return OnExec(topic, data); - } -#endif }; class IPCServ : public wxServer diff --git a/src/AudacityApp.h b/src/AudacityApp.h index 011307a7a..617f3666a 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -230,56 +230,6 @@ class AudacityApp:public wxApp { extern AudacityApp & wxGetApp(); - -#if defined(__WXMAC__) -inline void EnableAntialiasing(wxDC & dc) -{ - dc.GetGraphicsContext()->EnableOffset(false); - dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_DEFAULT); -} - -inline void DisableAntialiasing(wxDC & dc) -{ - dc.GetGraphicsContext()->EnableOffset(true); - dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE); -} - -inline void DrawText(wxDC & dc, const wxString & text, wxCoord x, wxCoord y) -{ - wxGraphicsContext *ctx = dc.GetGraphicsContext(); - wxAntialiasMode mode = ctx->GetAntialiasMode(); - if (mode == wxANTIALIAS_NONE) - { - dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_DEFAULT); - } - - dc.DrawText(text, x, y); - - if (mode == wxANTIALIAS_NONE) - { - dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE); - } -} - -inline void DrawText(wxDC *dc, const wxString & text, wxCoord x, wxCoord y) -{ - DrawText(*dc, text, x, y); -} - -#else -#define EnableAntialiasing(dc) -#define DisableAntialiasing(dc) -inline void DrawText(wxDC & dc, const wxString & text, wxCoord x, wxCoord y) -{ - dc.DrawText(text, x, y); -} - -inline void DrawText(wxDC * dc, const wxString & text, wxCoord x, wxCoord y) -{ - dc->DrawText(text, x, y); -} -#endif - #endif #define MAX_AUDIO (1. - 1./(1<<15)) diff --git a/src/FileIO.cpp b/src/FileIO.cpp index 69f44c690..afddfcc11 100644 --- a/src/FileIO.cpp +++ b/src/FileIO.cpp @@ -11,9 +11,7 @@ #include "Audacity.h" #include -#if wxCHECK_VERSION(3,0,0) #include -#endif #include #include diff --git a/src/LabelDialog.cpp b/src/LabelDialog.cpp index 64624127c..fdfdc9de4 100644 --- a/src/LabelDialog.cpp +++ b/src/LabelDialog.cpp @@ -73,11 +73,7 @@ enum { BEGIN_EVENT_TABLE(LabelDialog, wxDialog) EVT_GRID_SELECT_CELL(LabelDialog::OnSelectCell) -#if wxCHECK_VERSION(3,0,0) EVT_GRID_CELL_CHANGED(LabelDialog::OnCellChange) -#else - EVT_GRID_CELL_CHANGE(LabelDialog::OnCellChange) -#endif EVT_BUTTON(ID_INSERTA, LabelDialog::OnInsert) EVT_BUTTON(ID_INSERTB, LabelDialog::OnInsert) EVT_BUTTON(ID_REMOVE, LabelDialog::OnRemove) diff --git a/src/MixerBoard.cpp b/src/MixerBoard.cpp index 8deac9143..21efd54f3 100644 --- a/src/MixerBoard.cpp +++ b/src/MixerBoard.cpp @@ -335,14 +335,9 @@ MixerTrackCluster::MixerTrackCluster(wxWindow* parent, #endif // wxUSE_TOOLTIPS #ifdef __WXMAC__ -#if wxCHECK_VERSION(3, 0, 0) wxSizeEvent event(GetSize(), GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); -#else - wxSizeEvent dummyEvent; - this->OnSize(dummyEvent); -#endif UpdateGain(); #endif } diff --git a/src/Project.cpp b/src/Project.cpp index c5c6cebfa..b4eb8fb97 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -4760,7 +4760,7 @@ void AudacityProject::SetSnapTo(int snap) } } -int AudacityProject::GetSnapTo() +int AudacityProject::GetSnapTo() const { return mSnapTo; } diff --git a/src/Project.h b/src/Project.h index 451affea7..81fd01274 100644 --- a/src/Project.h +++ b/src/Project.h @@ -159,7 +159,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, sampleFormat GetDefaultFormat() { return mDefaultFormat; } - double GetRate() { return mRate; } + double GetRate() const { return mRate; } bool ZoomInAvailable() const { return mViewInfo.ZoomInAvailable(); } bool ZoomOutAvailable() const { return mViewInfo.ZoomOutAvailable(); } double GetSel0() { return mViewInfo.selectedRegion.t0(); } @@ -344,7 +344,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, // Snap To void SetSnapTo(int snap); - int GetSnapTo(); + int GetSnapTo() const; // Selection Format diff --git a/src/ShuttleGui.cpp b/src/ShuttleGui.cpp index 8970a6ece..52ce171cc 100644 --- a/src/ShuttleGui.cpp +++ b/src/ShuttleGui.cpp @@ -2068,28 +2068,6 @@ GuiWaveTrack * ShuttleGui::AddGuiWaveTrack( const wxString & WXUNUSED(Name)) #endif } -AdornedRulerPanel * ShuttleGui::AddAdornedRuler( ViewInfo *pViewInfo ) -{ - UseUpId(); - if( mShuttleMode != eIsCreating ) - return (AdornedRulerPanel*)NULL; -// return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), AdornedRulerPanel); - AdornedRulerPanel * pAdornedRuler; - miProp=0; - mpWind = pAdornedRuler = new AdornedRulerPanel( - mpParent, - miId, - wxDefaultPosition, - wxDefaultSize, - pViewInfo - ); - - mpWind->SetMinSize(wxSize(100,28)); - UpdateSizers(); - return pAdornedRuler; -} - - RulerPanel * ShuttleGui::AddRulerVertical(float low, float hi, const wxString & Units ) { UseUpId(); diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index 3839c7ab0..2d05a0cbe 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -322,7 +322,6 @@ extern void SetIfCreated( wxTextCtrl *&Var, wxTextCtrl * Val ); extern void SetIfCreated( wxStaticText *&Var, wxStaticText * Val ); class GuiWaveTrack; -class AdornedRulerPanel; class RulerPanel; class AttachableScrollBar; class ViewInfo; @@ -368,7 +367,6 @@ public: // Prop() sets the proportion value, defined as in wxSizer::Add(). ShuttleGui & Prop( int iProp ){ ShuttleGuiBase::Prop(iProp); return *this;}; // Has to be here too, to return a ShuttleGui and not a ShuttleGuiBase. GuiWaveTrack * AddGuiWaveTrack( const wxString & Name); - AdornedRulerPanel * AddAdornedRuler( ViewInfo *pViewInfo ); RulerPanel * AddRulerVertical( float low, float hi, const wxString & Units ); AttachableScrollBar * AddAttachableScrollBar( long style = wxSB_HORIZONTAL ); void AddStandardButtons( long buttons = eOkButton | eCancelButton, wxButton *extra = NULL ); diff --git a/src/Snap.cpp b/src/Snap.cpp index 1b7d9bc1a..9c7a5818f 100644 --- a/src/Snap.cpp +++ b/src/Snap.cpp @@ -8,101 +8,155 @@ **********************************************************************/ -#include "Snap.h" - -#include -#include +#include #include "LabelTrack.h" -#include "Project.h" #include "TrackPanel.h" #include "WaveTrack.h" #include "widgets/NumericTextCtrl.h" -// Change this to "true" to snap to nearest and "false" to snap to previous -// As of 2013/10/23, defaulting to "true" until a decision is made on -// which method is prefered. -#define SNAP_TO_NEAREST false +#include "Snap.h" + +#include + +WX_DEFINE_USER_EXPORTED_OBJARRAY(TrackClipArray); static int CompareSnapPoints(SnapPoint *s1, SnapPoint *s2) { return (s1->t - s2->t > 0? 1 : -1); } -SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, - const std::vector *pLabelTrackExclusions, - const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap) - : mConverter(NumericConverter::TIME) - , mPixelTolerance(std::max(0, pixelTolerance)) - , mZoomInfo(zoomInfo) +SnapManager::SnapManager(TrackList *tracks, + const ZoomInfo *zoomInfo, + const TrackClipArray *clipExclusions, + const TrackArray *trackExclusions, + bool noTimeSnap, + int pixelTolerance) +: mConverter(NumericConverter::TIME), + mSnapPoints(CompareSnapPoints) { - int i; + mTracks = tracks; + mZoomInfo = zoomInfo; + mClipExclusions = clipExclusions; + mTrackExclusions = trackExclusions; + mPixelTolerance = pixelTolerance; + mNoTimeSnap = noTimeSnap; - // Grab time-snapping prefs (unless otherwise requested) - mSnapToTime = false; + mProject = GetActiveProject(); + wxASSERT(mProject); - AudacityProject *p = GetActiveProject(); - wxASSERT(p); - if (p) - { - // Look up the format string - if (p->GetSnapTo() && !noTimeSnap) { - mSnapToTime = true; - mConverter.SetSampleRate(p->GetRate()); - mConverter.SetFormatName(p->GetSelectionFormat()); - } - } - - mSnapPoints = new SnapPointArray(CompareSnapPoints); + mSnapTo = 0; + mRate = 0.0; + mFormat.Empty(); // Two time points closer than this are considered the same mEpsilon = 1 / 44100.0; - // Add a SnapPoint at t=0 - mSnapPoints->Add(new SnapPoint(0.0, NULL)); + Reinit(); +} - TrackListIterator iter(tracks); - for (Track *track = iter.First(); track; track = iter.Next()) { - if (track->GetKind() == Track::Label) { - if (pLabelTrackExclusions) { - const std::vector::const_iterator - begin = pLabelTrackExclusions->begin(), - end = pLabelTrackExclusions->end(); - if (end != std::find(begin, end, track)) - continue; - } +SnapManager::~SnapManager() +{ + for (size_t i = 0, cnt = mSnapPoints.GetCount(); i < cnt; ++i) + { + delete mSnapPoints[i]; + } +} + +void SnapManager::Reinit() +{ + int snapTo = mProject->GetSnapTo(); + double rate = mProject->GetRate(); + wxString format = mProject->GetSelectionFormat(); + + // No need to reinit if these are still the same + if (snapTo == mSnapTo && rate == mRate && format == mFormat) + { + return; + } + + // Save new settings + mSnapTo = snapTo; + mRate = rate; + mFormat = format; + + // Clear snap points + for (size_t i = 0, cnt = mSnapPoints.GetCount(); i < cnt; ++i) + { + delete mSnapPoints[i]; + } + mSnapPoints.Clear(); + + // Grab time-snapping prefs (unless otherwise requested) + mSnapToTime = false; + + // Look up the format string + if (mSnapTo != SNAP_OFF && !mNoTimeSnap) + { + mSnapToTime = true; + mConverter.SetSampleRate(mRate); + mConverter.SetFormatName(mFormat); + } + + // Add a SnapPoint at t=0 + mSnapPoints.Add(new SnapPoint(0.0, NULL)); + + TrackListIterator iter(mTracks); + for (Track *track = iter.First(); track; track = iter.Next()) + { + if (mTrackExclusions && mTrackExclusions->Index(track) != wxNOT_FOUND) + { + continue; + } + + if (track->GetKind() == Track::Label) + { LabelTrack *labelTrack = (LabelTrack *)track; - for(i = 0; i < labelTrack->GetNumLabels(); i++) { + for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i) + { const LabelStruct *label = labelTrack->GetLabel(i); const double t0 = label->getT0(); const double t1 = label->getT1(); CondListAdd(t0, labelTrack); - if (t1 != t0) { + if (t1 != t0) + { CondListAdd(t1, labelTrack); } } } - else if (track->GetKind() == Track::Wave) { + else if (track->GetKind() == Track::Wave) + { WaveTrack *waveTrack = (WaveTrack *)track; WaveClipList::compatibility_iterator it; - for (it=waveTrack->GetClipIterator(); it; it=it->GetNext()) { + for (it = waveTrack->GetClipIterator(); it; it = it->GetNext()) + { WaveClip *clip = it->GetData(); - if (exclusions) { + if (mClipExclusions) + { bool skip = false; - for(int j=0; j<(int)exclusions->size(); j++) { - if ((*exclusions)[j].track == waveTrack && - (*exclusions)[j].clip == clip) + for (size_t j = 0, cnt = mClipExclusions->GetCount(); j < cnt; ++j) + { + if (mClipExclusions->Item(j).track == waveTrack && + mClipExclusions->Item(j).clip == clip) + { skip = true; + break; + } } + if (skip) + { continue; + } } + CondListAdd(clip->GetStartTime(), waveTrack); CondListAdd(clip->GetEndTime(), waveTrack); } } #ifdef USE_MIDI - else if (track->GetKind() == Track::Note) { + else if (track->GetKind() == Track::Note) + { CondListAdd(track->GetStartTime(), track); CondListAdd(track->GetEndTime(), track); } @@ -111,132 +165,150 @@ SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, } // Adds to mSnapPoints, filtering by TimeConverter -void SnapManager::CondListAdd(double t, Track *tr) +void SnapManager::CondListAdd(double t, Track *track) { - if (mSnapToTime) { + if (mSnapToTime) + { mConverter.SetValue(t); } - if (!mSnapToTime || mConverter.GetValue() == t) { - mSnapPoints->Add(new SnapPoint(t, tr)); + if (!mSnapToTime || mConverter.GetValue() == t) + { + mSnapPoints.Add(new SnapPoint(t, track)); } } -SnapManager::~SnapManager() -{ - int len = (int)mSnapPoints->GetCount(); - int i; - for(i = 0; i < len; i++) - delete (*mSnapPoints)[i]; - delete mSnapPoints; -} - // Return the time of the SnapPoint at a given index -double SnapManager::Get(int index) +double SnapManager::Get(size_t index) { - return (*mSnapPoints)[index]->t; + return mSnapPoints[index]->t; } // Returns the difference in time between t and the point at a given index -wxInt64 SnapManager::PixelDiff(double t, int index) +wxInt64 SnapManager::PixelDiff(double t, size_t index) { - return abs( - mZoomInfo.TimeToPosition(t, 0) - - mZoomInfo.TimeToPosition(Get(index), 0) - ); + return std::abs(mZoomInfo->TimeToPosition(t, 0) - + mZoomInfo->TimeToPosition(Get(index), 0)); } // Find the index where this SnapPoint should go in // sorted order, between i0 (inclusive) and i1 (exclusive). -int SnapManager::Find(double t, int i0, int i1) +size_t SnapManager::Find(double t, size_t i0, size_t i1) { if (i1 <= i0 + 1) + { return i0; + } + + size_t half = (i0 + i1) / 2; - int half = (i0 + i1) / 2; if (t < Get(half)) + { return Find(t, i0, half); - else - return Find(t, half, i1); + } + + return Find(t, half, i1); } // Find the SnapPoint nearest to time t -int SnapManager::Find(double t) +size_t SnapManager::Find(double t) { - int len = (int)mSnapPoints->GetCount(); - int index = Find(t, 0, len); + size_t cnt = mSnapPoints.GetCount(); + int index = Find(t, 0, cnt); // At this point, either index is the closest, or the next one // to the right is. Keep moving to the right until we get a // different value int next = index + 1; - while(next+1 < len && Get(next) == Get(index)) + while (next + 1 < cnt && Get(next) == Get(index)) + { next++; + } // Now return whichever one is closer to time t - if (next < len && PixelDiff(t, next) < PixelDiff(t, index)) + if (next < cnt && PixelDiff(t, next) < PixelDiff(t, index)) + { return next; - else - return index; + } + + return index; } // Helper: performs snap-to-points for Snap(). Returns true if a snap happened. bool SnapManager::SnapToPoints(Track *currentTrack, double t, bool rightEdge, - double *out_t) + double *outT) { - int len = (int)mSnapPoints->GetCount(); - *out_t = t; - if (len == 0) + *outT = t; + + size_t cnt = mSnapPoints.GetCount(); + if (cnt == 0) + { return false; + } // Find the nearest SnapPoint - int index = Find(t); + size_t index = Find(t); // If it's too far away, just give up now if (PixelDiff(t, index) >= mPixelTolerance) + { return false; + } // Otherwise, search left and right for all of the points // within the allowed range. - int left = index; - int right = index; - int i; + size_t left = index; + size_t right = index; + size_t i; - while(left > 0 && PixelDiff(t, left-1) < mPixelTolerance) + while (left > 0 && PixelDiff(t, left - 1) < mPixelTolerance) + { left--; + } - while(right < len-1 && PixelDiff(t, right+1) < mPixelTolerance) + while (right < cnt - 1 && PixelDiff(t, right + 1) < mPixelTolerance) + { right++; + } - if (left == index && right == index) { + if (left == index && right == index) + { // Awesome, there's only one point that matches! - *out_t = Get(index); + *outT = Get(index); return true; } - int indexInThisTrack = -1; - int countInThisTrack = 0; - for(i=left; i<=right; i++) { - if ((*mSnapPoints)[i]->track == currentTrack) { + size_t indexInThisTrack = -1; + size_t countInThisTrack = 0; + for (i = left; i <= right; ++i) + { + if (mSnapPoints[i]->track == currentTrack) + { indexInThisTrack = i; countInThisTrack++; } } - if (countInThisTrack == 1) { + + if (countInThisTrack == 1) + { // Cool, only one of the points is in the same track, so // we'll use that one. - *out_t = Get(indexInThisTrack); + *outT = Get(indexInThisTrack); return true; } - if (Get(right) - Get(left) < mEpsilon) { + if (Get(right) - Get(left) < mEpsilon) + { // OK, they're basically the same point if (rightEdge) - *out_t = Get(right); // Return rightmost - else - *out_t = Get(left); // Return leftmost + { + *outT = Get(right); // Return rightmost + } + else { + *outT = Get(left); // Return leftmost + } return true; } @@ -247,26 +319,32 @@ bool SnapManager::SnapToPoints(Track *currentTrack, bool SnapManager::Snap(Track *currentTrack, double t, bool rightEdge, - double *out_t, + double *outT, bool *snappedPoint, bool *snappedTime) { + // Check to see if we need to reinitialize + Reinit(); + // First snap to points in mSnapPoints - *out_t = t; - *snappedPoint = SnapToPoints(currentTrack, t, rightEdge, out_t); + *outT = t; + *snappedPoint = SnapToPoints(currentTrack, t, rightEdge, outT); // Now snap to the time grid *snappedTime = false; - if (mSnapToTime) { - if (*snappedPoint) { + if (mSnapToTime) + { + if (*snappedPoint) + { // Since mSnapPoints only contains points on the grid, we're done *snappedTime = true; } - else { + else + { // Snap time to the grid mConverter.ValueToControls(t, GetActiveProject()->GetSnapTo() == SNAP_NEAREST); mConverter.ControlsToValue(); - *out_t = mConverter.GetValue(); + *outT = mConverter.GetValue(); *snappedTime = true; } } diff --git a/src/Snap.h b/src/Snap.h index 284a0e7cf..26e99e966 100644 --- a/src/Snap.h +++ b/src/Snap.h @@ -15,28 +15,30 @@ #ifndef __AUDACITY_SNAP__ #define __AUDACITY_SNAP__ -#include - #include +#include +#include +#include "Project.h" +#include "Track.h" +#include "ViewInfo.h" +#include "WaveClip.h" #include "widgets/NumericTextCtrl.h" -class LabelTrack; -class Track; -class WaveClip; -class TrackList; -class ZoomInfo; - class TrackClip { public: - TrackClip(Track *t, WaveClip *c) { track = origTrack = t; clip = c; } + TrackClip(Track *t, WaveClip *c) + { + track = origTrack = t; + clip = c; + } Track *track; Track *origTrack; WaveClip *clip; }; -typedef std::vector TrackClipArray; +WX_DECLARE_USER_EXPORTED_OBJARRAY(TrackClip, TrackClipArray, AUDACITY_DLL_API); enum { @@ -45,9 +47,13 @@ enum SNAP_PRIOR }; -class SnapPoint { - public: - SnapPoint(double t, Track *track) { +const int kPixelTolerance = 4; + +class SnapPoint +{ +public: + SnapPoint(double t, Track *track) + { this->t = t; this->track = track; } @@ -57,12 +63,15 @@ class SnapPoint { WX_DEFINE_SORTED_ARRAY(SnapPoint *, SnapPointArray); -class SnapManager { +class SnapManager +{ public: - SnapManager(TrackList *tracks, TrackClipArray *exclusions, - const std::vector *pLabelTrackExclusions, - const ZoomInfo &zoomInfo, int pixelTolerance, bool noTimeSnap = false); - + SnapManager(TrackList *tracks, + const ZoomInfo *zoomInfo, + const TrackClipArray *clipExclusions = NULL, + const TrackArray *trackExclusions = NULL, + bool noTimeSnap = false, + int pixelTolerance = kPixelTolerance); ~SnapManager(); // The track may be NULL. @@ -70,11 +79,11 @@ public: // Pass rightEdge=true if this is the right edge of a selection, // and false if it's the left edge. bool Snap(Track *currentTrack, - double t, - bool rightEdge, - double *out_t, - bool *snappedPoint, - bool *snappedTime); + double t, + bool rightEdge, + double *outT, + bool *snappedPoint, + bool *snappedTime); static wxArrayString GetSnapLabels(); static wxArrayString GetSnapValues(); @@ -82,23 +91,35 @@ public: static int GetSnapIndex(const wxString & value); private: - void CondListAdd(double t, Track *tr); - double Get(int index); - wxInt64 PixelDiff(double t, int index); - int Find(double t, int i0, int i1); - int Find(double t); - bool SnapToPoints(Track *currentTrack, double t, bool rightEdge, - double *out_t); - double mEpsilon; - SnapPointArray *mSnapPoints; + void Reinit(); + void CondListAdd(double t, Track *track); + double Get(size_t index); + wxInt64 PixelDiff(double t, size_t index); + size_t Find(double t, size_t i0, size_t i1); + size_t Find(double t); + bool SnapToPoints(Track *currentTrack, double t, bool rightEdge, double *outT); + +private: + + const AudacityProject *mProject; + TrackList *mTracks; + const TrackClipArray *mClipExclusions; + const TrackArray *mTrackExclusions; + const ZoomInfo *mZoomInfo; + int mPixelTolerance; + bool mNoTimeSnap; + + double mEpsilon; + SnapPointArray mSnapPoints; // Info for snap-to-time - NumericConverter mConverter; - bool mSnapToTime; + NumericConverter mConverter; + bool mSnapToTime; - const wxInt64 mPixelTolerance; - const ZoomInfo &mZoomInfo; + int mSnapTo; + double mRate; + wxString mFormat; }; #endif diff --git a/src/Tags.cpp b/src/Tags.cpp index 8e170de2f..272784d6e 100644 --- a/src/Tags.cpp +++ b/src/Tags.cpp @@ -636,11 +636,7 @@ enum { }; BEGIN_EVENT_TABLE(TagsEditor, wxDialog) -#if wxCHECK_VERSION(3,0,0) EVT_GRID_CELL_CHANGED(TagsEditor::OnChange) -#else - EVT_GRID_CELL_CHANGE(TagsEditor::OnChange) -#endif EVT_BUTTON(EditID, TagsEditor::OnEdit) EVT_BUTTON(ResetID, TagsEditor::OnReset) EVT_BUTTON(ClearID, TagsEditor::OnClear) diff --git a/src/Track.h b/src/Track.h index 00dd5faf8..1e3bf6c55 100644 --- a/src/Track.h +++ b/src/Track.h @@ -30,11 +30,13 @@ class wxTextFile; class DirManager; class UndoStack; +class Track; class LabelTrack; class TimeTrack; class WaveTrack; class AudacityProject; +WX_DEFINE_USER_EXPORTED_ARRAY(Track*, TrackArray, class AUDACITY_DLL_API); WX_DEFINE_USER_EXPORTED_ARRAY(WaveTrack*, WaveTrackArray, class AUDACITY_DLL_API); #if defined(USE_MIDI) diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index fe4817901..3007f21be 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -156,6 +156,7 @@ audio tracks. #include #include #include +#include #include #include #include @@ -325,10 +326,6 @@ void TrackArtist::DrawTracks(TrackList * tracks, bool bigPoints, bool drawSliders) { -#if defined(__WXMAC__) - dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE); -#endif - wxRect trackRect = rect; wxRect stereoTrackRect; TrackListIterator iter(tracks); @@ -459,6 +456,11 @@ void TrackArtist::DrawTrack(const Track * t, bool muted = (hasSolo || t->GetMute()) && !t->GetSolo(); +#if defined(__WXMAC__) || defined(__WXGTK__) + wxAntialiasMode aamode = dc.GetGraphicsContext()->GetAntialiasMode(); + dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE); +#endif + switch (wt->GetDisplay()) { case WaveTrack::Waveform: DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo, @@ -468,6 +470,11 @@ void TrackArtist::DrawTrack(const Track * t, DrawSpectrum(wt, dc, rect, selectedRegion, zoomInfo); break; } + +#if defined(__WXMAC__) || defined(__WXGTK__) + dc.GetGraphicsContext()->SetAntialiasMode(aamode); +#endif + if (mbShowTrackNameInWaveform && // Exclude right channel of stereo track !(!wt->GetLinked() && wt->GetLink())) { diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 5cb533d87..0f71f22f5 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -78,11 +78,6 @@ *//**************************************************************//** -\class TrackClip -\brief One clip (i.e short section) of a WaveTrack. - -*//**************************************************************//** - \class TrackPanelListener \brief A now badly named class which is used to give access to a subset of the TrackPanel methods from all over the place. @@ -383,7 +378,6 @@ BEGIN_EVENT_TABLE(TrackPanel, wxWindow) EVT_KEY_UP(TrackPanel::OnKeyUp) EVT_CHAR(TrackPanel::OnChar) EVT_SIZE(TrackPanel::OnSize) - EVT_ERASE_BACKGROUND(TrackPanel::OnErase) EVT_PAINT(TrackPanel::OnPaint) EVT_SET_FOCUS(TrackPanel::OnSetFocus) EVT_KILL_FOCUS(TrackPanel::OnKillFocus) @@ -435,62 +429,9 @@ wxCursor * MakeCursor( int WXUNUSED(CursorId), const char * pXpm[36], int HotX, Image.SetMaskColour(255,0,0); Image.SetMask();// Enable mask. -#if defined(__WXGTK__) && !wxCHECK_VERSION(3, 0, 0) - // - // Kludge: the wxCursor Image constructor is broken in wxGTK. - // This code, based loosely on the broken code from the wxGTK source, - // works around the problem by constructing a 1-bit bitmap and - // calling the other custom cursor constructor. - // - // -DMM - // - - unsigned char *rgbBits = Image.GetData(); - int w = Image.GetWidth() ; - int h = Image.GetHeight(); - int imagebitcount = (w*h)/8; - - unsigned char *bits = new unsigned char [imagebitcount]; - unsigned char *maskBits = new unsigned char [imagebitcount]; - - int i, j, i8; - unsigned char cMask; - for (i=0; i 127) - maskBits[i] = maskBits[i] | cMask; - cMask = cMask * 2; - } - } - - pCursor = new wxCursor((const char *)bits, w, h, - HotX-HotAdjust, HotY-HotAdjust, - (const char *)maskBits); - - delete [] bits; - delete [] maskBits; - -#else Image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, HotX-HotAdjust ); Image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, HotY-HotAdjust ); pCursor = new wxCursor( Image ); -#endif return pCursor; } @@ -516,6 +457,7 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, mRuler(ruler), mTrackArtist(NULL), mBacking(NULL), + mResizeBacking(false), mRefreshBacking(false), mConverter(NumericConverter::TIME), mAutoScrolling(false), @@ -527,11 +469,18 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, { SetLabel(_("Track Panel")); SetName(_("Track Panel")); + SetBackgroundStyle(wxBG_STYLE_PAINT); mAx = new TrackPanelAx( this ); #if wxUSE_ACCESSIBILITY SetAccessible( mAx ); #endif + + // Preinit the backing DC and bitmap so routines that require it will + // not cause a crash if they run before the panel is fully initialized. + mBacking = new wxBitmap(1, 1); + mBackingDC.SelectObject(*mBacking); + mMouseCapture = IsUncaptured; mSlideUpDownOnly = false; mLabelTrackStartXPos=-1; @@ -1141,6 +1090,7 @@ void TrackPanel::OnTimer() } TimerUpdateIndicator(); + DrawOverlays(false); if(IsAudioActive() && gAudioIO->GetNumCaptureChannels()) { @@ -1204,50 +1154,44 @@ void TrackPanel::ScrollDuringDrag() } } -#if 0 -// now unused -/// This updates the indicator (on a timer tick) that shows -/// where the current play or record position is. To do this, -/// we cheat a little. The indicator is drawn during the ruler -/// drawing process (that should probably change, but...), so -/// we create a memory DC and tell the ruler to draw itself there, -/// and then just blit that to the screen. -/// The indicator is a small triangle, red for record, green for play. -void TrackPanel::DrawIndicator() +void TrackPanel::DrawQuickPlayIndicator(int x, bool snapped) { - wxClientDC dc( this ); - DoDrawIndicator( dc ); -} + wxClientDC dc(this); + + // Erase the old indicator. + if (mOldQPIndicatorPos != x) { +#if defined(__WXMAC__) + // On OSX, if a HiDPI resolution is being used, the line will actually take up + // more than 1 pixel (even though it is drawn as 1), so we restore the surrounding + // pixels as well. (This is because the wxClientDC doesn't know about the scaling.) + dc.Blit(mOldQPIndicatorPos - 1, 0, 3, mBacking->GetHeight(), &mBackingDC, mOldQPIndicatorPos - 1, 0); +#else + dc.Blit(mOldQPIndicatorPos, 0, 1, mBacking->GetHeight(), &mBackingDC, mOldQPIndicatorPos, 0); #endif -void TrackPanel::DrawQuickPlayIndicator(wxDC & dc, double pos) -{ - // Erase the old indicator. - if( mOldQPIndicatorPos != -1 ) { - dc.Blit( mOldQPIndicatorPos, 0, 1, mBacking->GetHeight(), &mBackingDC, mOldQPIndicatorPos, 0 ); mOldQPIndicatorPos = -1; } - if (pos >= 0) { - - (mRuler->mIsSnapped)? AColor::SnapGuidePen( &dc) : AColor::Light( &dc, false); + if (x >= 0) { + snapped ? AColor::SnapGuidePen(&dc) : AColor::Light(&dc, false); // Draw indicator in all visible tracks - VisibleTrackIterator iter( GetProject() ); - for( Track *t = iter.First(); t; t = iter.Next() ) + VisibleTrackIterator iter(GetProject()); + for (Track *t = iter.First(); t; t = iter.Next()) { // Convert virtual coordinate to physical int y = t->GetY() - mViewInfo->vpos; // Draw the new indicator in its new location AColor::Line(dc, - pos, - y + kTopMargin, - pos, - // Minus one more because AColor::Line includes both endpoints - y + t->GetHeight() - kBottomMargin - 1 ); + x, + y + kTopMargin, + x, + // Minus one more because AColor::Line includes both endpoints + y + t->GetHeight() - kBottomMargin - 1 ); } - mOldQPIndicatorPos = pos; + + mOldQPIndicatorPos = x; } } @@ -1342,7 +1286,15 @@ void TrackPanel::UndrawIndicator(wxDC & dc) mLastIndicatorX = w - 1; } + // Restore the old position from the backing DC. +#if defined(__WXMAC__) + // On OSX, if a HiDPI resolution is being used, the line will actually take up + // more than 1 pixel (even though it is drawn as 1), so we restore the surrounding + // pixels as well. (This is because the wxClientDC doesn't know about the scaling.) + dc.Blit(mLastIndicatorX - 1, 0, 3, mBacking->GetHeight(), &mBackingDC, mLastIndicatorX - 1, 0); +#else dc.Blit(mLastIndicatorX, 0, 1, mBacking->GetHeight(), &mBackingDC, mLastIndicatorX, 0); +#endif } mRuler->ClearIndicator(); @@ -1437,7 +1389,14 @@ void TrackPanel::UndrawCursor(wxDC & dc) mLastCursorX, GetLeftOffset() + width); if( onScreen ) +#if defined(__WXMAC__) + // On OSX, if a HiDPI resolution is being used, the line will actually take up + // more than 1 pixel (even though it is drawn as 1), so we restore the surrounding + // pixels as well. (This is because the wxClientDC doesn't know about the scaling.) + dc.Blit(mLastCursorX - 1, 0, 3, mBacking->GetHeight(), &mBackingDC, mLastCursorX - 1, 0); +#else dc.Blit(mLastCursorX, 0, 1, mBacking->GetHeight(), &mBackingDC, mLastCursorX, 0); +#endif } } @@ -1492,38 +1451,12 @@ void TrackPanel::DoDrawCursor(wxDC & dc) /// OnSize() is called when the panel is resized void TrackPanel::OnSize(wxSizeEvent & /* event */) { - int width, height; - GetSize( &width, &height ); - - // wxMac doesn't like zero dimensions, so protect against it - width = width == 0 ? 1 : width; - height = height == 0 ? 1 : height; - - // (Re)allocate the backing bitmap - if( mBacking ) - { - mBackingDC.SelectObject( wxNullBitmap ); - delete mBacking; - } - - mBacking = new wxBitmap( width, height ); - mBackingDC.SelectObject( *mBacking ); - DisableAntialiasing(mBackingDC); + // Tell OnPaint() to recreate the backing bitmap + mResizeBacking = true; // Refresh the entire area. Really only need to refresh when // expanding...is it worth the trouble? - Refresh( false ); -} - -/// OnErase( ) is called during the normal course of -/// completing an erase operation. -void TrackPanel::OnErase(wxEraseEvent & /* event */) -{ - // Ignore it for now. This reduces flashing when dragging windows - // over track area while playing or recording. - // - // However, if artifacts or the like are discovered later, then - // we could blit the backing bitmap here. + Refresh(); } /// AS: OnPaint( ) is called during the normal course of @@ -1536,8 +1469,7 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */) // Construct the paint DC on the heap so that it may be deleted // early - wxDC *dc = new wxPaintDC(this); - DisableAntialiasing(*dc); + wxPaintDC *dc = new wxPaintDC(this); // Retrieve the damage rectangle wxRect box = GetUpdateRegion().GetBox(); @@ -1549,6 +1481,25 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */) // Reset (should a mutex be used???) mRefreshBacking = false; + if (mResizeBacking) + { + // Reset + mResizeBacking = false; + + // Delete the backing bitmap + if (mBacking) + { + mBackingDC.SelectObject(wxNullBitmap); + delete mBacking; + mBacking = NULL; + } + + wxSize sz = GetClientSize(); + mBacking = new wxBitmap(); + mBacking->Create(sz.x, sz.y); //, *dc); + mBackingDC.SelectObject(*mBacking); + } + // Redraw the backing bitmap DrawTracks(&mBackingDC); @@ -1557,20 +1508,22 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */) } else { - // Copy full, possibly clipped, damage rectange + // Copy full, possibly clipped, damage rectangle dc->Blit(box.x, box.y, box.width, box.height, &mBackingDC, box.x, box.y); } // Done with the clipped DC delete dc; - // Drawing now goes directly to the client area + // Drawing now goes directly to the client area. It can't use the paint DC + // becuase the paint DC might be clipped and DrawOverlays() may need to draw + // outside the clipped region. DrawOverlays(true); #if DEBUG_DRAW_TIMING - sw.Pause(); - wxLogDebug(wxT("Total: %ld milliseconds"), sw.Time()); - wxPrintf(wxT("Total: %ld milliseconds\n"), sw.Time()); + sw.Pause(); + wxLogDebug(wxT("Total: %ld milliseconds"), sw.Time()); + wxPrintf(wxT("Total: %ld milliseconds\n"), sw.Time()); #endif } @@ -2244,7 +2197,7 @@ void TrackPanel::HandleSelect(wxMouseEvent & event) selectedClip->GetOffset(), selectedClip->GetEndTime()); } //Also, capture this track for dragging until we up-click. - mCapturedClipArray.push_back(TrackClip(w, selectedClip)); + mCapturedClipArray.Add(TrackClip(w, selectedClip)); mMouseCapture = IsSliding; @@ -2583,9 +2536,7 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, if (mSnapManager) delete mSnapManager; - mSnapManager = new SnapManager(mTracks, NULL, NULL, - *mViewInfo, - 4); // pixel tolerance + mSnapManager = new SnapManager(mTracks, mViewInfo); mSnapLeft = -1; mSnapRight = -1; @@ -3925,7 +3876,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) mHSlideAmount = 0.0; mDidSlideVertically = false; - std::vector trackExclusions; + mTrackExclusions.Clear(); Track *vt = FindTrack(event.m_x, event.m_y, false, false, &rect); if (!vt) @@ -3963,7 +3914,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) // The captured clip is the focus, but we need to create a list // of all clips that have to move, also... - mCapturedClipArray.clear(); + mCapturedClipArray.Clear(); // First, if click was in selection, capture selected clips; otherwise // just the clicked-on clip @@ -3973,12 +3924,12 @@ void TrackPanel::StartSlide(wxMouseEvent & event) if (t->GetSelected()) { AddClipsToCaptured(t, true); if (t->GetKind() != Track::Wave) - trackExclusions.push_back(t); + mTrackExclusions.Add(t); } } } else { - mCapturedClipArray.push_back(TrackClip(vt, mCapturedClip)); + mCapturedClipArray.Add(TrackClip(vt, mCapturedClip)); // Check for stereo partner Track *partner = mTracks->GetLink(vt); @@ -3992,7 +3943,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) if (s0 >= 0) { WaveClip *clip = ((WaveTrack *)partner)->GetClipAtSample(s0); if (clip) { - mCapturedClipArray.push_back(TrackClip(partner, clip)); + mCapturedClipArray.Add(TrackClip(partner, clip)); } } } @@ -4019,7 +3970,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) mCapturedClipArray[i].clip->GetStartTime(), mCapturedClipArray[i].clip->GetEndTime() ); if (t->GetKind() != Track::Wave) - trackExclusions.push_back(t); + mTrackExclusions.Add(t); } } #ifdef USE_MIDI @@ -4032,7 +3983,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) { AddClipsToCaptured(t, nt->GetStartTime(), nt->GetEndTime()); if (t->GetKind() != Track::Wave) - trackExclusions.push_back(t); + mTrackExclusions.Add(t); } } #endif @@ -4041,7 +3992,7 @@ void TrackPanel::StartSlide(wxMouseEvent & event) } else { mCapturedClip = NULL; - mCapturedClipArray.clear(); + mCapturedClipArray.Clear(); } mSlideUpDownOnly = event.CmdDown() && !multiToolModeActive; @@ -4058,10 +4009,9 @@ void TrackPanel::StartSlide(wxMouseEvent & event) if (mSnapManager) delete mSnapManager; mSnapManager = new SnapManager(mTracks, + mViewInfo, &mCapturedClipArray, - &trackExclusions, - *mViewInfo, - 4, // pixel tolerance + &mTrackExclusions, true); // don't snap to time mSnapLeft = -1; mSnapRight = -1; @@ -4109,7 +4059,7 @@ void TrackPanel::AddClipsToCaptured(Track *t, double t0, double t1) } if (newClip) - mCapturedClipArray.push_back(TrackClip(t, clip)); + mCapturedClipArray.Add(TrackClip(t, clip)); } it = it->GetNext(); } @@ -4136,7 +4086,7 @@ void TrackPanel::AddClipsToCaptured(Track *t, double t0, double t1) return; } #endif - mCapturedClipArray.push_back(TrackClip(t, NULL)); + mCapturedClipArray.Add(TrackClip(t, NULL)); } } } @@ -7552,7 +7502,6 @@ void TrackPanel::TimerUpdateScrubbing() wxCoord width, height; { wxClientDC dc(this); - DisableAntialiasing(dc); static const wxFont labelFont(24, wxSWISS, wxNORMAL, wxNORMAL); dc.SetFont(labelFont); dc.GetTextExtent(mScrubSpeedText, &width, &height); @@ -7583,11 +7532,22 @@ std::pair TrackPanel::GetScrubSpeedRectangle() void TrackPanel::UndrawScrubSpeed(wxDC & dc) { if (!mLastScrubRect.IsEmpty()) +#if defined(__WXMAC__) + // On OSX, if a HiDPI resolution is being used, the line will actually take up + // more than 1 pixel (even though it is drawn as 1), so we restore the surrounding + // pixels as well. (This is because the wxClientDC doesn't know about the scaling.) + dc.Blit( + mLastScrubRect.GetX() - 1, mLastScrubRect.GetY(), + mLastScrubRect.GetWidth() + 3, mLastScrubRect.GetHeight(), + &mBackingDC, + mLastScrubRect.GetX() - 1, mLastScrubRect.GetY()); +#else dc.Blit( mLastScrubRect.GetX(), mLastScrubRect.GetY(), mLastScrubRect.GetWidth(), mLastScrubRect.GetHeight(), &mBackingDC, mLastScrubRect.GetX(), mLastScrubRect.GetY()); +#endif } void TrackPanel::DoDrawScrubSpeed(wxDC &dc) @@ -7621,7 +7581,7 @@ void TrackPanel::DoDrawScrubSpeed(wxDC &dc) #endif dc.SetTextForeground(clrNoScroll); - DrawText(dc, mScrubSpeedText, mLastScrubRect.GetX(), mLastScrubRect.GetY()); + dc.DrawText(mScrubSpeedText, mLastScrubRect.GetX(), mLastScrubRect.GetY()); } } #endif @@ -7721,15 +7681,15 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec, mTrackInfo.DrawSliders(dc, (WaveTrack *)t, rect); if (!t->GetMinimized()) { - int offset = 8; + int offset = 8; if (rect.y + 22 + 12 < rec.y + rec.height - 19) - DrawText(dc, TrackSubText(t), + dc->DrawText(TrackSubText(t), trackRect.x + offset, trackRect.y + 22); if (rect.y + 38 + 12 < rec.y + rec.height - 19) - DrawText(dc, GetSampleFormatStr(((WaveTrack *) t)->GetSampleFormat()), + dc->DrawText(GetSampleFormatStr(((WaveTrack *) t)->GetSampleFormat()), trackRect.x + offset, trackRect.y + 38); } @@ -7848,7 +7808,6 @@ void TrackPanel::DrawOverlays(bool repaint) { // Drawing now goes directly to the client area wxClientDC dc(this); - DisableAntialiasing(dc); // See what requires redrawing. If repainting, all. // If not, then whatever is outdated, and whatever will be damaged by @@ -7874,36 +7833,30 @@ void TrackPanel::DrawOverlays(bool repaint) if (repaint || pairs[0].second) { wxClientDC dc(this); - DisableAntialiasing(dc); UndrawIndicator(dc); } if (repaint || pairs[1].second) { wxClientDC dc(this); - DisableAntialiasing(dc); UndrawCursor(dc); } #ifdef EXPERIMENTAL_SCRUBBING_BASIC if (repaint || pairs[2].second) { wxClientDC dc(this); - DisableAntialiasing(dc); UndrawScrubSpeed(dc); } #endif if (repaint || pairs[0].second) { wxClientDC dc(this); - DisableAntialiasing(dc); DoDrawIndicator(dc); } if (repaint || pairs[1].second) { wxClientDC dc(this); - DisableAntialiasing(dc); DoDrawCursor(dc); } #ifdef EXPERIMENTAL_SCRUBBING_BASIC if (repaint || pairs[2].second) { wxClientDC dc(this); - DisableAntialiasing(dc); DoDrawScrubSpeed(dc); } #endif @@ -10509,7 +10462,7 @@ void TrackInfo::DrawTitleBar(wxDC * dc, const wxRect & rect, Track * t, // in and out of the title bar. So clear it first. AColor::MediumTrackInfo(dc, t->GetSelected()); dc->DrawRectangle(bev); - DrawText(dc, titleStr, bev.x + 2, bev.y + (bev.height - textHeight) / 2); + dc->DrawText(titleStr, bev.x + 2, bev.y + (bev.height - textHeight) / 2); // Pop-up triangle #ifdef EXPERIMENTAL_THEMING @@ -10572,7 +10525,7 @@ void TrackInfo::DrawMuteSolo(wxDC * dc, const wxRect & rect, Track * t, SetTrackInfoFont(dc); dc->GetTextExtent(str, &textWidth, &textHeight); - DrawText(dc, str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2); + dc->DrawText(str, bev.x + (bev.width - textWidth) / 2, bev.y + (bev.height - textHeight) / 2); AColor::BevelTrackInfo(*dc, (solo?t->GetSolo():t->GetMute()) == down, bev); @@ -10632,12 +10585,12 @@ void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect rect) const GetGainRect(rect, sliderRect); if (sliderRect.y + sliderRect.height < rect.y + rect.height - 19) { - GainSlider(t)->OnPaint(*dc, t->GetSelected()); + GainSlider(t)->OnPaint(*dc); } GetPanRect(rect, sliderRect); if (sliderRect.y + sliderRect.height < rect.y + rect.height - 19) { - PanSlider(t)->OnPaint(*dc, t->GetSelected()); + PanSlider(t)->OnPaint(*dc); } } diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 3edcc5f44..112891148 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -27,6 +27,7 @@ #include "WaveTrackLocation.h" #include "Snap.h" +#include "Track.h" class wxMenu; class wxRect; @@ -140,7 +141,6 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel { virtual void UpdatePrefs(); virtual void OnSize(wxSizeEvent & event); - virtual void OnErase(wxEraseEvent & event); virtual void OnPaint(wxPaintEvent & event); virtual void OnMouseEvent(wxMouseEvent & event); virtual void OnCaptureLost(wxMouseCaptureLostEvent & event); @@ -232,7 +232,7 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel { virtual void UpdateTrackVRuler(Track *t); virtual void UpdateVRulerSize(); - virtual void DrawQuickPlayIndicator(wxDC & dc, double pos); + virtual void DrawQuickPlayIndicator(int x, bool snapped = false); // Returns the time corresponding to the pixel column one past the track area // (ignoring any fisheye) @@ -615,12 +615,13 @@ protected: int mNewCursorX; // Quick-Play indicator postion - double mOldQPIndicatorPos; + int mOldQPIndicatorPos; int mTimeCount; wxMemoryDC mBackingDC; wxBitmap *mBacking; + bool mResizeBacking; bool mRefreshBacking; int mPrevWidth; int mPrevHeight; @@ -670,6 +671,7 @@ protected: Envelope *mCapturedEnvelope; WaveClip *mCapturedClip; TrackClipArray mCapturedClipArray; + TrackArray mTrackExclusions; bool mCapturedClipIsSelection; WaveTrackLocation mCapturedTrackLocation; wxRect mCapturedTrackLocationRect; diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index f0be05ed6..1ee927498 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -2831,39 +2831,6 @@ EffectUIHost::~EffectUIHost() // wxWindow implementation // ============================================================================ -#if defined(__WXMAC__) - -// As mentioned below, we want to manipulate the window attributes, but doing -// so causes extra events to fire and those events lead to the rebuilding of -// the menus. Unfortunately, if this happens when a modal dialog is displayed -// the menus become disabled until the menubar is completely rebuilt, like when -// leaving preferecnes. -// -// So, we only do this when NOT displaying a modal dialog since that's really -// only when it is needed. - -bool EffectUIHost::Show(bool show) -{ - if (!mIsModal) - { -#if !wxCHECK_VERSION(3, 0, 0) - // We want the effects windows on the Mac to float above the project window - // but still have normal modal dialogs appear above the effects windows and - // not let the effect windows fall behind the project window. - // - // This seems to accomplish that, but time will be the real judge. - WindowRef windowRef = (WindowRef) MacGetWindowRef(); - WindowGroupRef parentGroup = GetWindowGroup((WindowRef) ((wxFrame *)wxGetTopLevelParent(mParent))->MacGetWindowRef()); - ChangeWindowGroupAttributes(parentGroup, kWindowGroupAttrSharedActivation, kWindowGroupAttrMoveTogether); - SetWindowGroup(windowRef, parentGroup); -#endif - } - mIsModal = false; - - return wxDialog::Show(show); -} -#endif - bool EffectUIHost::TransferDataToWindow() { return mEffect->TransferDataToWindow(); @@ -2880,11 +2847,6 @@ bool EffectUIHost::TransferDataFromWindow() int EffectUIHost::ShowModal() { -#if defined(__WXMAC__) - // See explanation in EffectUIHost::Show() - mIsModal = true; -#endif - #if defined(__WXMSW__) // Swap the Close and Apply buttons wxSizer *sz = mApplyBtn->GetContainingSizer(); diff --git a/src/effects/Effect.h b/src/effects/Effect.h index 8486350da..0b499d9fb 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -506,10 +506,6 @@ public: EffectUIClientInterface *client); virtual ~EffectUIHost(); -#if defined(__WXMAC__) - virtual bool Show(bool show = true); -#endif - virtual bool TransferDataToWindow(); virtual bool TransferDataFromWindow(); @@ -560,10 +556,6 @@ private: bool mIsGUI; bool mIsBatch; -#if defined(__WXMAC__) - bool mIsModal; -#endif - wxButton *mApplyBtn; wxButton *mCloseBtn; wxButton *mMenuBtn; diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index d969f51d0..65fb67231 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -558,14 +558,6 @@ int ExportPCM::Export(AudacityProject *project, ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) AddID3Chunk(fName, metadata, sf_format); -#ifdef __WXMAC__ -#if !wxCHECK_VERSION(3, 0, 0) - wxFileName fn(fName); - fn.MacSetTypeAndCreator(sf_header_mactype(sf_format & SF_FORMAT_TYPEMASK), - AUDACITY_CREATOR); -#endif -#endif - return updateResult; } diff --git a/src/import/ImportPCM.cpp b/src/import/ImportPCM.cpp index b8a1df1e0..99d431860 100644 --- a/src/import/ImportPCM.cpp +++ b/src/import/ImportPCM.cpp @@ -542,11 +542,7 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory, if((mInfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) len = wxUINT32_SWAP_ON_LE(len); -#if wxCHECK_VERSION(3,0,0) - if (wxStricmp(id, "ID3 ") != 0) { // must be case insensitive -#else - if (Stricmp(id, "ID3 ") != 0) { // must be case insensitive -#endif + if (wxStricmp(id, "ID3 ") != 0) { // must be case insensitive f.Seek(len + (len & 0x01), wxFromCurrent); continue; } diff --git a/src/prefs/PrefsDialog.cpp b/src/prefs/PrefsDialog.cpp index 6dc15f307..7393b40d0 100644 --- a/src/prefs/PrefsDialog.cpp +++ b/src/prefs/PrefsDialog.cpp @@ -30,11 +30,7 @@ #include -#if wxCHECK_VERSION(2, 8, 4) #include -#else -#include "../widgets/treebook.h" -#endif #include "../AudioIO.h" #include "../Experimental.h" diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index 8a856a3c9..48fb4f208 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -647,13 +647,8 @@ int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion, else { // msmeyer: Show error message if stream could not be opened wxMessageBox( -#if wxCHECK_VERSION(3,0,0) _("Error while opening sound device. " "Please check the playback device settings and the project sample rate."), -#else - _("Error while opening sound device. " - wxT("Please check the playback device settings and the project sample rate.")), -#endif _("Error"), wxOK | wxICON_EXCLAMATION, this); } } diff --git a/src/toolbars/DeviceToolBar.cpp b/src/toolbars/DeviceToolBar.cpp index 33d86bd89..1b9161e43 100644 --- a/src/toolbars/DeviceToolBar.cpp +++ b/src/toolbars/DeviceToolBar.cpp @@ -76,14 +76,9 @@ void DeviceToolBar::Create(wxWindow *parent) ToolBar::Create(parent); // Simulate a size event to set initial meter placement/size -#if wxCHECK_VERSION(3, 0, 0) wxSizeEvent event(GetSize(), GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); -#else - wxSizeEvent dummy; - OnSize(dummy); -#endif } void DeviceToolBar::DeinitChildren() diff --git a/src/widgets/ASlider.cpp b/src/widgets/ASlider.cpp index 01ca55c9a..9fddf9d4e 100644 --- a/src/widgets/ASlider.cpp +++ b/src/widgets/ASlider.cpp @@ -72,14 +72,6 @@ or ASlider. #include "../Theme.h" #include "../AllThemeResources.h" -//#include "../../images/SliderThumb.xpm" - -#include "../../images/SliderThumbAlpha.xpm" -#include "../../images/SliderThumbDisabled.xpm" -#include "../../images/SliderThumb_Vertical.xpm" -#include "../../images/SliderThumb_VerticalAlpha.xpm" -#include "../../images/SliderThumb_VerticalDisabled.xpm" - #if defined __WXMSW__ const int sliderFontSize = 10; #else @@ -96,8 +88,9 @@ class TipPanel : public wxPopupWindow TipPanel(wxWindow *parent, const wxString & label); virtual ~TipPanel() {} - void SetLabel(const wxString & label); + wxSize GetSize() const; void SetPos(const wxPoint & pos); + void SetLabel(const wxString & label); private: void OnPaint(wxPaintEvent & event); @@ -140,9 +133,14 @@ TipPanel::TipPanel(wxWindow *parent, const wxString & maxLabel) #endif } +wxSize TipPanel::GetSize() const +{ + return wxSize(mWidth, mHeight); +} + void TipPanel::SetPos(const wxPoint & pos) { - SetSize(pos.x - mWidth/2, pos.y, mWidth, mHeight); + SetSize(pos.x, pos.y, mWidth, mHeight); } void TipPanel::SetLabel(const wxString & label) @@ -153,7 +151,6 @@ void TipPanel::SetLabel(const wxString & label) void TipPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) { wxAutoBufferedPaintDC dc(this); - DisableAntialiasing(dc); dc.SetPen(*wxBLACK_PEN); dc.SetBrush(AColor::tooltipBrush); @@ -164,7 +161,7 @@ void TipPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) int textWidth, textHeight; dc.GetTextExtent(mLabel, &textWidth, &textHeight); - DrawText(dc, mLabel, (mWidth - textWidth) / 2, (mHeight - textHeight) / 2); + dc.DrawText(mLabel, (mWidth - textWidth) / 2, (mHeight - textHeight) / 2); } #if defined(__WXGTK__) @@ -264,6 +261,85 @@ float SliderDialog::Get() // LWSlider // +// Define the thumb outline +static const wxPoint2DDouble outer[] = +{ + wxPoint2DDouble( 2, 0 ), + wxPoint2DDouble( 8, 0 ), + wxPoint2DDouble( 10, 2 ), + wxPoint2DDouble( 10, 8 ), + wxPoint2DDouble( 5, 13 ), + wxPoint2DDouble( 0, 8 ), + wxPoint2DDouble( 0, 2 ), + wxPoint2DDouble( 2, 0 ) +}; + +// Define the left and top interior components when enabled +static const wxPoint2DDouble enabledLeftBegin[] = +{ + wxPoint2DDouble( 2, 1 ), + wxPoint2DDouble( 1, 2 ), + wxPoint2DDouble( 1, 8 ), + wxPoint2DDouble( 4, 4 ), + wxPoint2DDouble( 4, 7 ) +}; +static const wxPoint2DDouble enabledLeftEnd[] = +{ + wxPoint2DDouble( 8, 1 ), + wxPoint2DDouble( 1, 8 ), + wxPoint2DDouble( 5, 12 ), + wxPoint2DDouble( 6, 4 ), + wxPoint2DDouble( 6, 7 ) +}; + +// Define right and bottom interior components when enabled +static const wxPoint2DDouble enabledRightBegin[] = +{ + wxPoint2DDouble( 9, 2 ), + wxPoint2DDouble( 9, 8 ), + wxPoint2DDouble( 4, 5 ), + wxPoint2DDouble( 4, 8 ), +}; +static const wxPoint2DDouble enabledRightEnd[] = +{ + wxPoint2DDouble( 9, 8 ), + wxPoint2DDouble( 6, 11 ), + wxPoint2DDouble( 6, 5 ), + wxPoint2DDouble( 6, 8 ) +}; + +// Define the interior stripes when disabled +static const wxPoint2DDouble disabledStripesBegin[] = +{ + wxPoint2DDouble( 3, 2 ), + wxPoint2DDouble( 5, 2 ), + wxPoint2DDouble( 7, 2 ), + wxPoint2DDouble( 2, 3 ), + wxPoint2DDouble( 2, 5 ), + wxPoint2DDouble( 2, 7 ), +}; +static const wxPoint2DDouble disabledStripesEnd[] = +{ + wxPoint2DDouble( 8, 7 ), + wxPoint2DDouble( 8, 5 ), + wxPoint2DDouble( 8, 3 ), + wxPoint2DDouble( 7, 8 ), + wxPoint2DDouble( 6, 9 ), + wxPoint2DDouble( 5, 10 ), +}; + +// Define the right and bottom interior components when disabled +static const wxPoint2DDouble disabledRightBegin[] = +{ + wxPoint2DDouble( 9, 2 ), + wxPoint2DDouble( 9, 8 ), +}; +static const wxPoint2DDouble disabledRightEnd[] = +{ + wxPoint2DDouble( 9, 8 ), + wxPoint2DDouble( 6, 11 ), +}; + // Construct customizable slider LWSlider::LWSlider(wxWindow * parent, wxString name, @@ -433,24 +509,31 @@ void LWSlider::Init(wxWindow * parent, mDefaultShortcut = false; mBitmap = NULL; mThumbBitmap = NULL; - mThumbBitmapAllocated = false; mScrollLine = 1.0f; mScrollPage = 5.0f; mTipPanel = NULL; mpRuler = NULL; // Do this and Move() before Draw(). Move(pos); - Draw(); } LWSlider::~LWSlider() { - delete mBitmap; - if (mThumbBitmapAllocated) { - delete mThumbBitmap; + if (mBitmap) + { + delete mBitmap; + mBitmap = NULL; } + + if (mThumbBitmap) + { + delete mThumbBitmap; + mThumbBitmap = NULL; + } + delete mpRuler; - if (mTipPanel) { + if (mTipPanel) + { delete mTipPanel; } } @@ -494,8 +577,13 @@ void LWSlider::Move(const wxPoint &newpos) mTop = newpos.y; } -void LWSlider::OnPaint(wxDC &dc, bool WXUNUSED(selected)) +void LWSlider::OnPaint(wxDC &dc) { + if (!mBitmap || !mThumbBitmap) + { + Draw(dc); + } + //thumbPos should be in pixels int thumbPos = ValueToPosition(mCurrentValue); int thumbOrtho; // position in axis orthogonal to mOrientation @@ -504,28 +592,27 @@ void LWSlider::OnPaint(wxDC &dc, bool WXUNUSED(selected)) else thumbOrtho = mCenterX - (mThumbWidth/2); -#if defined(__WXMSW__) +#if !defined(__WXMAC__) if( mHW ) { dc.Clear(); } #endif -#if defined(__WXGTK__) - if (mHW) - { - dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BACKGROUND)); - dc.Clear(); - } -#endif dc.DrawBitmap(*mBitmap, mLeft, mTop, true); if (mOrientation == wxHORIZONTAL) + { dc.DrawBitmap(*mThumbBitmap, mLeft+thumbPos, mTop+thumbOrtho, true); + } else + { dc.DrawBitmap(*mThumbBitmap, mLeft+thumbOrtho, mTop+thumbPos, true); + } if (mTipPanel) + { mTipPanel->Update(); + } } void LWSlider::OnSize( wxSizeEvent & event ) @@ -533,83 +620,105 @@ void LWSlider::OnSize( wxSizeEvent & event ) mWidth = event.GetSize().GetX(); mHeight = event.GetSize().GetY(); - Draw(); - Refresh(); } -void LWSlider::Draw() +void LWSlider::Draw(wxDC & paintDC) { - // - // Get the thumb slider bitmap - // - // AD: Setting the mThumbBitmap pointer requires caution, because - // ownership of the object pointed to varies. If we've allocated - // mThumbBitmap we must delete it first, and we must set - // mThumbBitmapAllocated according to whether we have. - // - - if (mEnabled && mOrientation == wxHORIZONTAL) - { - if (mThumbBitmapAllocated) - delete mThumbBitmap; - mThumbBitmap = &theTheme.Bitmap( bmpSliderThumb ); - mThumbBitmapAllocated = false; - } - //v \todo Convert this to an image in AllThemeResources, as bmpSliderThumb. Make an alpha also, as for horizontal slider thumb? - else if (mOrientation == wxHORIZONTAL) - { - wxImage thumbImage(wxBitmap(SliderThumbDisabled).ConvertToImage()); - - if (mThumbBitmapAllocated) - delete mThumbBitmap; - mThumbBitmap = new wxBitmap(thumbImage); - mThumbBitmapAllocated = true; - - mThumbBitmap->SetMask(new wxMask(wxBitmap(SliderThumbAlpha), *wxBLACK)); - } - else if (mEnabled) - { - wxImage thumbImage(wxBitmap(SliderThumb_Vertical).ConvertToImage()); - if (mThumbBitmapAllocated) - delete mThumbBitmap; - mThumbBitmap = new wxBitmap(thumbImage); - mThumbBitmapAllocated = true; - - mThumbBitmap->SetMask( - new wxMask(wxBitmap(SliderThumb_VerticalAlpha), *wxBLACK)); - } - else - { - wxImage thumbImage(wxBitmap( - SliderThumb_VerticalDisabled).ConvertToImage()); - - if (mThumbBitmapAllocated) - delete mThumbBitmap; - mThumbBitmap = new wxBitmap(thumbImage); - mThumbBitmapAllocated = true; - - mThumbBitmap->SetMask( - new wxMask(wxBitmap(SliderThumb_VerticalAlpha), *wxBLACK)); - } - - // - // Now the background bitmap - // - - if( mBitmap ) + if (mBitmap) { delete mBitmap; mBitmap = NULL; } - if (mOrientation == wxHORIZONTAL) - mCenterY = mHeight - 9; - else - mCenterX = mWidth - 9; + if (mThumbBitmap) + { + delete mThumbBitmap; + mThumbBitmap = NULL; + } - mThumbWidth = mThumbBitmap->GetWidth(); - mThumbHeight = mThumbBitmap->GetHeight(); + // The color we'll use to create the mask + wxColour transparentColour(255, 254, 255); + + // Set up the memory DC + wxMemoryDC dc; + + // Create the bitmap + mThumbWidth = 14; + mThumbHeight = 14; + mThumbBitmap = new wxBitmap(); + mThumbBitmap->Create(mThumbWidth, mThumbHeight, paintDC); + dc.SelectObject(*mThumbBitmap); + +#if !defined(__WXMAC__) + // Clear the background for our mask + dc.SetBackground(transparentColour); + dc.Clear(); +#endif + + // Create the graphics contexxt + wxGraphicsContext *gc = wxGraphicsContext::Create(dc); + + // For vertical, we use the same downward pointing thumb, but rotate and flip it + if (mOrientation == wxVERTICAL) + { + gc->Translate(0, 3); + gc->Scale(1, -1); + gc->Rotate((-90 * M_PI) / 180); + } + else + { + gc->Translate(1.5, 0); + } + + // Draw the thumb outline + gc->SetBrush(wxBrush(mEnabled ? wxColour(192, 192, 216) : wxColour(238, 238, 238))); + gc->SetPen(wxPen(mEnabled ? wxColour(0, 0, 0) : wxColour(119, 119, 119))); + gc->DrawLines(WXSIZEOF(outer), outer); + + // The interior is based on whether the slider is enabled or not + if (mEnabled) + { + // Draw the left and top interior components + gc->SetPen(wxPen(wxColour(255, 255, 255))); + gc->StrokeLines(WXSIZEOF(enabledLeftBegin), enabledLeftBegin, enabledLeftEnd); + + // Draw the right and bottom interior components + gc->SetPen(wxPen(wxColour(141, 141, 178))); + gc->StrokeLines(WXSIZEOF(enabledRightBegin), enabledRightBegin, enabledRightEnd); + } + else + { + // Draw the interior stripes + gc->SetPen(wxPen(wxColour(200, 200, 200))); + gc->StrokeLines(WXSIZEOF(disabledStripesBegin), disabledStripesBegin, disabledStripesEnd); + + // Draw the right and bottom interior components + gc->SetPen(wxPen(wxColour(153, 153, 153))); + gc->StrokeLines(WXSIZEOF(disabledRightBegin), disabledRightBegin, disabledRightEnd); + } + + // Done with the graphics context and memory DC + delete gc; + dc.SelectObject(wxNullBitmap); + +#if !defined(__WXMAC__) + // Now create and set the mask + mThumbBitmap->SetMask(new wxMask(*mThumbBitmap, transparentColour)); +#endif + + // + // Now the background bitmap + // + + if (mOrientation == wxHORIZONTAL) + { + mCenterY = mHeight - 9; + } + else + { + mCenterX = mWidth - 9; + } if (mOrientation == wxHORIZONTAL) { @@ -624,38 +733,35 @@ void LWSlider::Draw() mHeightY = mBottomY - mTopY; } - wxMemoryDC *dc = new wxMemoryDC(); - mBitmap = new wxBitmap(mWidth, mHeight); + mBitmap = new wxBitmap(); + mBitmap->Create(mWidth, mHeight, paintDC); + dc.SelectObject(*mBitmap); - // Set background to an unused color. This allows for easy - // mask creation. And garbage can be displayed if it isn't - // cleared. - dc->SelectObject(*mBitmap); - -#if defined(__WXMAC__) - dc->GetGraphicsContext()->EnableOffset(); - dc->GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE); -#endif - - wxColour TransparentColour = wxColour( 255, 254, 255 ); // DO-THEME Mask colour!! JC-Aug-2007 // Needed with experimental theming! // ... because windows blends against this colour. #ifdef EXPERIMENTAL_THEMING - TransparentColour = theTheme.Colour( clrTrackInfo ); + transparentColour = theTheme.Colour(clrTrackInfo); +#else + transparentColour = wxColour(255, 254, 255); #endif - dc->SetBackground( wxBrush( TransparentColour ) ); - dc->Clear(); +#if !defined(__WXMAC__) + dc.SetBackground(transparentColour); + dc.Clear(); +#endif // Draw the line along which the thumb moves. - AColor::Dark(dc, false); + AColor::Dark(&dc, false); if (mOrientation == wxHORIZONTAL) - AColor::Line(*dc, mLeftX, mCenterY+1, mRightX+2, mCenterY+1); + { + AColor::Line(dc, mLeftX, mCenterY+1, mRightX+2, mCenterY+1); + } else //v if (mStyle != DB_SLIDER) // Let the ruler do it for vertical DB_SLIDER. - AColor::Line(*dc, mCenterX+1, mTopY, mCenterX+1, mBottomY+2); - + { + AColor::Line(dc, mCenterX+1, mTopY, mCenterX+1, mBottomY+2); + } // Draw +/- or L/R first. We need to draw these before the tick marks. if (mStyle == PAN_SLIDER) @@ -665,51 +771,46 @@ void LWSlider::Draw() // sliderFontSize is for the tooltip. // we need something smaller here... wxFont labelFont(sliderFontSize-3, wxSWISS, wxNORMAL, wxNORMAL); - dc->SetFont(labelFont); + dc.SetFont(labelFont); // Colors #ifdef EXPERIMENTAL_THEMING - dc->SetTextForeground( theTheme.Colour( clrTrackPanelText )); + dc.SetTextForeground( theTheme.Colour( clrTrackPanelText )); // TransparentColour should be same as clrTrackInfo. - dc->SetTextBackground( theTheme.Colour( clrTrackInfo ) ); - dc->SetBackground( theTheme.Colour( clrTrackInfo ) ); + dc.SetTextBackground( theTheme.Colour( clrTrackInfo ) ); + dc.SetBackground( theTheme.Colour( clrTrackInfo ) ); // HAVE to use solid and not transparent here, // otherwise windows will do it's clever font optimisation trick, // but against a default colour of white, which is not OK on a dark // background. - dc->SetBackgroundMode( wxSOLID ); + dc.SetBackgroundMode( wxSOLID ); #else - if (mEnabled) - dc->SetTextForeground( wxColour( 0,0,0) ); - else - dc->SetTextForeground( wxColour(128, 128, 128)); - - dc->SetTextBackground( wxColour( 255,255,255)); + dc.SetTextForeground(mEnabled ? wxColour(0, 0, 0) : wxColour(128, 128, 128)); + dc.SetTextBackground(wxColour(255,255,255)); #endif /* i18n-hint: One-letter abbreviation for Left, in the Pan slider */ - dc->DrawText(_("L"), mLeftX, 0); + dc.DrawText(_("L"), mLeftX, 0); /* i18n-hint: One-letter abbreviation for Right, in the Pan slider */ - dc->DrawText(_("R"), mRightX-6,0); - } else + dc.DrawText(_("R"), mRightX-6,0); + } + else { // draw the '-' and the '+' #ifdef EXPERIMENTAL_THEMING wxPen pen( theTheme.Colour( clrTrackPanelText )); - dc->SetPen( pen ); + dc.SetPen( pen ); #else - if (mEnabled) - dc->SetPen(*wxBLACK_PEN); - else - dc->SetPen(wxColour(128, 128, 128)); + dc.SetPen(mEnabled ? *wxBLACK : wxColour(128, 128, 128)); #endif + if (mOrientation == wxHORIZONTAL) { - AColor::Line(*dc, mLeftX, mCenterY-10, mLeftX+4, mCenterY-10); - AColor::Line(*dc, mRightX-5, mCenterY-10, mRightX-1, mCenterY-10); - AColor::Line(*dc, mRightX-3, mCenterY-12, mRightX-3, mCenterY-8); + AColor::Line(dc, mLeftX, mCenterY-10, mLeftX+4, mCenterY-10); + AColor::Line(dc, mRightX-5, mCenterY-10, mRightX-1, mCenterY-10); + AColor::Line(dc, mRightX-3, mCenterY-12, mRightX-3, mCenterY-8); } else { @@ -718,9 +819,9 @@ void LWSlider::Draw() // Draw '+' and '-' only for other vertical sliders. if (mStyle != DB_SLIDER) { - AColor::Line(*dc, mCenterX-12, mBottomY-3, mCenterX-8, mBottomY-3); - AColor::Line(*dc, mCenterX-12, mTopY+3, mCenterX-8, mTopY+3); - AColor::Line(*dc, mCenterX-10, mTopY, mCenterX-10, mTopY+5); + AColor::Line(dc, mCenterX-12, mBottomY-3, mCenterX-8, mBottomY-3); + AColor::Line(dc, mCenterX-12, mTopY+3, mCenterX-8, mTopY+3); + AColor::Line(dc, mCenterX-10, mTopY, mCenterX-10, mTopY+5); } } } @@ -758,7 +859,9 @@ void LWSlider::Draw() int divs = 10; double upp; if (mOrientation == wxHORIZONTAL) + { upp = divs / (double)(mWidthX-1); + } else { if (mStyle == DB_SLIDER) @@ -768,34 +871,42 @@ void LWSlider::Draw() double d = 0.0; int int_d = -1; const int kMax = (mOrientation == wxHORIZONTAL) ? mWidthX : mHeightY; - for(int p = 0; p <= kMax; p++) { - if (((int)d) > int_d) { + for(int p = 0; p <= kMax; p++) + { + if (((int)d) > int_d) + { int_d = (int)d; int tickLength = ((int_d == 0) || (int_d == divs)) ? 5: 3; // longer ticks at extremes - AColor::Light(dc, false); + AColor::Light(&dc, false); if (mOrientation == wxHORIZONTAL) - AColor::Line(*dc, mLeftX+p, mCenterY-tickLength, mLeftX+p, mCenterY-1); // ticks above + { + AColor::Line(dc, mLeftX+p, mCenterY-tickLength, mLeftX+p, mCenterY-1); // ticks above + } else - AColor::Line(*dc, mCenterX-tickLength, mTopY+p, mCenterX-1, mTopY+p); // ticks at left + { + AColor::Line(dc, mCenterX-tickLength, mTopY+p, mCenterX-1, mTopY+p); // ticks at left + } - AColor::Dark(dc, false); + AColor::Dark(&dc, false); if (mOrientation == wxHORIZONTAL) - AColor::Line(*dc, mLeftX+p+1, mCenterY-tickLength+1, mLeftX+p+1, mCenterY-1); // ticks above + { + AColor::Line(dc, mLeftX+p+1, mCenterY-tickLength+1, mLeftX+p+1, mCenterY-1); // ticks above + } else - AColor::Line(*dc, mCenterX-tickLength+1, mTopY+p+1, mCenterX-1, mTopY+p+1); // ticks at left + { + AColor::Line(dc, mCenterX-tickLength+1, mTopY+p+1, mCenterX-1, mTopY+p+1); // ticks at left + } } d += upp; } } - dc->SelectObject(wxNullBitmap); + dc.SelectObject(wxNullBitmap); - // Must preceed creating the mask as that will attempt to - // select the bitmap into another DC. - delete dc; - - mBitmap->SetMask( new wxMask( *mBitmap, TransparentColour ) ); +#if !defined(__WXMAC__) + mBitmap->SetMask(new wxMask(*mBitmap, transparentColour)); +#endif } void LWSlider::SetToolTipTemplate(const wxString & tip) @@ -842,26 +953,27 @@ void LWSlider::CreatePopWin() mTipPanel = NULL; } - wxString mintip = GetTip(mMinValue); - wxString maxtip = GetTip(mMaxValue); - mTipPanel = new TipPanel(mParent, mintip.Length() > maxtip.Length() ? mintip : maxtip); + mTipPanel = new TipPanel(mParent, GetMaxTip()); } void LWSlider::SetPopWinPosition() { - wxPoint pt; - - if (mOrientation == wxHORIZONTAL) - { - pt = wxPoint(mWidth/2 + mLeft, mHeight + mTop + 1); - } - else - { - pt = wxPoint(mWidth + mLeft + 1, mHeight/2 + mTop); - } - if (mTipPanel) { + wxSize sz = mTipPanel->GetSize(); + wxPoint pt; + + if (mOrientation == wxHORIZONTAL) + { + pt.x = mLeft + ((mWidth - sz.x) / 2); + pt.y = mTop + mHeight + 1; + } + else + { + pt.x = mLeft + mWidth + 1; + pt.y = mTop + ((mHeight - sz.y) / 2); + } + mTipPanel->SetPos(mParent->ClientToScreen(pt)); } } @@ -892,7 +1004,11 @@ wxString LWSlider::GetTip(float value) const break; case DB_SLIDER: - val.Printf(wxT("%.3g dB"), value); + val.Printf(wxT("%+.1f dB"), value); + if (val.Right(1) == wxT("0")) + { + val.Left(val.Length() - 2); + } break; case PAN_SLIDER: @@ -931,6 +1047,49 @@ wxString LWSlider::GetTip(float value) const return label; } +wxString LWSlider::GetMaxTip() const +{ + wxString label; + + if (mTipTemplate.IsEmpty()) + { + wxString val; + + switch(mStyle) + { + case FRAC_SLIDER: + val.Printf(wxT("%d.99"), (int) mMinValue - mMaxValue); + break; + + case DB_SLIDER: + val = wxT("-99.999 dB"); + break; + + case PAN_SLIDER: + val = wxT("-100% Right"); + break; + + case SPEED_SLIDER: + val = wxT("9.99x"); + break; + +#ifdef EXPERIMENTAL_MIDI_OUT + case VEL_SLIDER: + val = wxT("+127"); + break; +#endif + } + + label.Printf(wxT("%s: %s"), mName.c_str(), val.c_str()); + } + else + { + label.Printf(mTipTemplate, floor(mMaxValue - mMinValue) + 0.999); + } + + return label; +} + bool LWSlider::ShowDialog() { return DoShowDialog( mParent->ClientToScreen(wxPoint( mLeft, mTop ) ) ); @@ -1386,7 +1545,13 @@ bool LWSlider::GetEnabled() void LWSlider::SetEnabled(bool enabled) { mEnabled = enabled; - Draw(); + + if (mThumbBitmap) + { + delete mThumbBitmap; + mThumbBitmap = NULL; + } + Refresh(); } @@ -1483,7 +1648,7 @@ void ASlider::OnPaint(wxPaintEvent & WXUNUSED(event)) this->SetBackgroundColour( Col ); #endif - mLWSlider->OnPaint(dc, false); + mLWSlider->OnPaint(dc); if ( mSliderIsFocused ) { diff --git a/src/widgets/ASlider.h b/src/widgets/ASlider.h index cf6b49ae6..7d22aba55 100644 --- a/src/widgets/ASlider.h +++ b/src/widgets/ASlider.h @@ -140,7 +140,7 @@ class LWSlider void Move(const wxPoint &newpos); - void OnPaint(wxDC &dc, bool selected); + void OnPaint(wxDC &dc); void OnSize(wxSizeEvent & event); void OnMouseEvent(wxMouseEvent & event); void OnKeyEvent(wxKeyEvent & event); @@ -157,10 +157,11 @@ class LWSlider private: wxString GetTip(float value) const; + wxString GetMaxTip() const; void FormatPopWin(); void SetPopWinPosition(); void CreatePopWin(); - void Draw(); + void Draw(wxDC & dc); bool DoShowDialog(wxPoint pos); diff --git a/src/widgets/KeyView.cpp b/src/widgets/KeyView.cpp index 76b03a8a7..29a16d311 100644 --- a/src/widgets/KeyView.cpp +++ b/src/widgets/KeyView.cpp @@ -54,8 +54,6 @@ KeyView::KeyView(wxWindow *parent, const wxPoint & pos, const wxSize & size) : wxVListBox(parent, id, pos, size, wxBORDER_THEME), - mOpen(NULL), - mClosed(NULL), mScrollX(0), mWidth(0) { @@ -65,36 +63,6 @@ KeyView::KeyView(wxWindow *parent, SetAccessible(mAx); #endif - // Create the device context - wxMemoryDC dc; - - // Create the open/expanded bitmap - mOpen = new wxBitmap(16, 16); - dc.SelectObject(*mOpen); - - dc.SetBrush(*wxWHITE_BRUSH); - dc.SetPen(*wxWHITE_PEN); - dc.DrawRectangle(0, 0, 16, 16); - - dc.SetPen(*wxBLACK_PEN); - dc.DrawRectangle(3, 4, 9, 9); - dc.DrawLine(5, 8, 10, 8); - dc.SelectObject(wxNullBitmap); - - // Create the closed/collapsed bitmap - mClosed = new wxBitmap(16, 16); - dc.SelectObject(*mClosed); - - dc.SetBrush(*wxWHITE_BRUSH); - dc.SetPen(*wxWHITE_PEN); - dc.DrawRectangle(0, 0, 16, 16); - - dc.SetPen(*wxBLACK_PEN); - dc.DrawRectangle(3, 4, 9, 9); - dc.DrawLine(7, 6, 7, 11); - dc.DrawLine(5, 8, 10, 8); - dc.SelectObject(wxNullBitmap); - // The default view mViewType = ViewByTree; @@ -104,16 +72,6 @@ KeyView::KeyView(wxWindow *parent, KeyView::~KeyView() { - // Cleanup - if (mOpen) - { - delete mOpen; - } - - if (mClosed) - { - delete mClosed; - } } // @@ -1098,7 +1056,7 @@ KeyView::OnDrawBackground(wxDC & dc, const wxRect & rect, size_t line) const } else { - // Non ocused lines get a light background + // Non focused lines get a light background dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE))); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(r); @@ -1142,15 +1100,28 @@ KeyView::OnDrawItem(wxDC & dc, const wxRect & rect, size_t line) const // Adjust left edge to account for scrolling wxCoord x = rect.x - mScrollX; - if (node->iscat) + if (node->iscat || node->ispfx) { - // Draw categories bitmap at left edge - dc.DrawBitmap(node->isopen ? *mOpen : *mClosed, x, rect.y); - } - else if (node->ispfx) - { - // Draw prefix bitmap to the right of the category bitmap - dc.DrawBitmap(node->isopen ? *mOpen : *mClosed, x + KV_BITMAP_SIZE, rect.y); + wxCoord bx = x; + wxCoord by = rect.y; + + if (node->ispfx) + { + bx += KV_BITMAP_SIZE; + } + + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.SetPen(*wxBLACK_PEN); + dc.DrawRectangle(bx + 3, by + 4, 9, 9); + if (node->isopen) + { + AColor::Line(dc, bx + 5, by + 8, bx + 9, by + 8); + } + else + { + AColor::Line(dc, bx + 7, by + 6, bx + 7, by + 10); + AColor::Line(dc, bx + 5, by + 8, bx + 9, by + 8); + } } // Indent text diff --git a/src/widgets/KeyView.h b/src/widgets/KeyView.h index 50ddf0a8a..59fe819af 100644 --- a/src/widgets/KeyView.h +++ b/src/widgets/KeyView.h @@ -13,8 +13,6 @@ #include #include -#include -#include #include #include #include @@ -145,9 +143,6 @@ private: #endif private: - wxBitmap *mOpen; - wxBitmap *mClosed; - KeyNodeArray mNodes; KeyNodeArrayPtr mLines; diff --git a/src/widgets/Meter.cpp b/src/widgets/Meter.cpp index 18aee1f51..0c9ca5bca 100644 --- a/src/widgets/Meter.cpp +++ b/src/widgets/Meter.cpp @@ -414,7 +414,8 @@ void Meter::OnErase(wxEraseEvent & WXUNUSED(event)) void Meter::OnPaint(wxPaintEvent & WXUNUSED(event)) { - wxDC *paintDC = wxAutoBufferedPaintDCFactory(this); +// wxDC *paintDC = wxAutoBufferedPaintDCFactory(this); + wxPaintDC *paintDC = new wxPaintDC(this); wxDC & destDC = *paintDC; if (mLayoutValid == false) @@ -425,10 +426,11 @@ void Meter::OnPaint(wxPaintEvent & WXUNUSED(event)) } // Create a new one using current size and select into the DC - mBitmap = new wxBitmap(mWidth, mHeight); + mBitmap = new wxBitmap(); + mBitmap->Create(mWidth, mHeight, destDC); wxMemoryDC dc; dc.SelectObject(*mBitmap); - + // Go calculate all of the layout metrics HandleLayout(dc); @@ -446,7 +448,7 @@ void Meter::OnPaint(wxPaintEvent & WXUNUSED(event)) dc.SetBrush(mBkgndBrush); dc.DrawRectangle(0, 0, mWidth, mHeight); #endif - + // MixerTrackCluster style has no icon or L/R labels if (mStyle != MixerTrackCluster) { @@ -1486,62 +1488,16 @@ void Meter::RepaintBarsNow() { if (mLayoutValid) { -#if defined(__WXMSW__) - wxClientDC clientDC(this); - wxBufferedDC dc(&clientDC, *mBitmap); -#else - wxClientDC dc(this); -#endif - + // Invalidate the bars so they get redrawn for (int i = 0; i < mNumBars; i++) { - DrawMeterBar(dc, &mBar[i]); + Refresh(false, &mBar[i].r); } -#if defined(__WXMAC__) || defined(__WXGTK__) - // Due to compositing or antialiasing on the Mac, we have to make - // sure all remnants of the previous ruler text is completely gone. - // Otherwise, we get a strange bolding effect. - // - // Since redrawing the rulers above wipe out most of the ruler, the - // only thing that is left is the bits between the bars. - if (mStyle == HorizontalStereoCompact) - { - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(mBkgndBrush); - dc.DrawRectangle(mBar[0].b.GetLeft(), - mBar[0].b.GetBottom() + 1, - mBar[0].b.GetWidth(), - mBar[1].b.GetTop() - mBar[0].b.GetBottom() - 1); - AColor::Bevel(dc, false, mBar[0].b); - AColor::Bevel(dc, false, mBar[1].b); - } - else if (mStyle == VerticalStereoCompact) - { - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(mBkgndBrush); - dc.DrawRectangle(mBar[0].b.GetRight() + 1, - mBar[0].b.GetTop(), - mBar[1].b.GetLeft() - mBar[0].b.GetRight() - 1, - mBar[0].b.GetHeight()); - AColor::Bevel(dc, false, mBar[0].b); - AColor::Bevel(dc, false, mBar[1].b); - } -#endif + // Immediate redraw (using wxPaintDC) + Update(); -#if defined(__WXMSW__) || defined(__WXGTK__) - if (mIsFocused) - { - wxRect r = mIconRect; - AColor::DrawFocus(dc, r.Inflate(1, 1)); - } -#endif - - // Compact style requires redrawing ruler - if (mStyle == HorizontalStereoCompact || mStyle == VerticalStereoCompact) - { - mRuler.Draw(dc); - } + return; } } diff --git a/src/widgets/Ruler.cpp b/src/widgets/Ruler.cpp index 533c65a0b..1ff7edf75 100644 --- a/src/widgets/Ruler.cpp +++ b/src/widgets/Ruler.cpp @@ -84,7 +84,6 @@ using std::min; using std::max; #define SELECT_TOLERANCE_PIXEL 4 -#define QUICK_PLAY_SNAP_PIXEL 4 // pixel tolerance for snap guides #define PLAY_REGION_TRIANGLE_SIZE 6 #define PLAY_REGION_RECT_WIDTH 1 @@ -136,14 +135,6 @@ Ruler::Ruler() mUserFonts = false; -#if !wxCHECK_VERSION(3, 0, 0) - #ifdef __WXMAC__ - mMinorMinorFont->SetNoAntiAliasing(true); - mMinorFont->SetNoAntiAliasing(true); - mMajorFont->SetNoAntiAliasing(true); - #endif -#endif - mMajorLabels = 0; mMinorLabels = 0; mMinorMinorLabels = 0; @@ -314,14 +305,6 @@ void Ruler::SetFonts(const wxFont &minorFont, const wxFont &majorFont, const wxF *mMinorFont = minorFont; *mMajorFont = majorFont; -#if !wxCHECK_VERSION(3, 0, 0) - #ifdef __WXMAC__ - mMinorMinorFont->SetNoAntiAliasing(true); - mMinorFont->SetNoAntiAliasing(true); - mMajorFont->SetNoAntiAliasing(true); - #endif -#endif - // Won't override these fonts mUserFonts = true; @@ -1534,13 +1517,10 @@ int Ruler::GetZeroPosition() void Ruler::GetMaxSize(wxCoord *width, wxCoord *height) { - if (!mValid) { - wxMemoryDC tmpDC; - wxBitmap tmpBM(1, 1); - tmpDC.SelectObject(tmpBM); - mDC = &tmpDC; - Update( NULL); + wxScreenDC sdc; + mDC = &sdc; + Update(NULL); } if (width) @@ -1644,7 +1624,7 @@ void RulerPanel::OnPaint(wxPaintEvent & WXUNUSED(evt)) void RulerPanel::OnSize(wxSizeEvent & WXUNUSED(evt)) { - Refresh(false); + Refresh(); } // LL: We're overloading DoSetSize so that we can update the ruler bounds immediately @@ -1683,7 +1663,6 @@ enum { }; BEGIN_EVENT_TABLE(AdornedRulerPanel, wxPanel) - EVT_ERASE_BACKGROUND(AdornedRulerPanel::OnErase) EVT_PAINT(AdornedRulerPanel::OnPaint) EVT_SIZE(AdornedRulerPanel::OnSize) EVT_MOUSE_EVENTS(AdornedRulerPanel::OnMouseEvents) @@ -1695,17 +1674,21 @@ BEGIN_EVENT_TABLE(AdornedRulerPanel, wxPanel) EVT_MENU(OnLockPlayRegionID, AdornedRulerPanel::OnLockPlayRegion) END_EVENT_TABLE() -AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, +AdornedRulerPanel::AdornedRulerPanel(AudacityProject* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - ViewInfo *viewinfo): - wxPanel( parent, id, pos, size ) + ViewInfo *viewinfo) +: wxPanel(parent, id, pos, size) { SetLabel( _("Timeline") ); SetName(GetLabel()); SetBackgroundStyle(wxBG_STYLE_PAINT); + mCursorDefault = wxCursor(wxCURSOR_DEFAULT); + mCursorHand = wxCursor(wxCURSOR_HAND); + mCursorSizeWE = wxCursor(wxCURSOR_SIZEWE); + mLeftOffset = 0; mCurTime = -1; mIndTime = -1; @@ -1720,7 +1703,6 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, mMouseEventState = mesNone; mIsDragging = false; - mBuffer = new wxBitmap( 1, 1 ); mViewInfo = viewinfo; mOuter = GetClientRect(); @@ -1731,13 +1713,15 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, mInner.width -= 2; // -2 for left and right bevels mInner.height -= 3; // -3 for top and bottom bevels and bottom line - ruler.SetUseZoomInfo(mLeftOffset); - ruler.SetBounds( mInner.GetLeft(), + mRuler.SetUseZoomInfo(mLeftOffset); + mRuler.SetBounds(mInner.GetLeft(), mInner.GetTop(), mInner.GetRight(), - mInner.GetBottom() ); - ruler.SetLabelEdges( false ); - ruler.SetFormat( Ruler::TimeFormat ); + mInner.GetBottom()); + mRuler.SetLabelEdges( false ); + mRuler.SetFormat( Ruler::TimeFormat ); + + mTracks = parent->GetTracks(); mSnapManager = NULL; mIsSnapped = false; @@ -1762,14 +1746,15 @@ AdornedRulerPanel::AdornedRulerPanel(wxWindow* parent, AdornedRulerPanel::~AdornedRulerPanel() { + // Done with the snap manager + if (mSnapManager) { + delete mSnapManager; + } + wxTheApp->Disconnect(EVT_AUDIOIO_CAPTURE, wxCommandEventHandler(AdornedRulerPanel::OnCapture), NULL, this); - delete mBuffer; - - if (mSnapManager) - delete mSnapManager; } void AdornedRulerPanel::UpdatePrefs() @@ -1779,7 +1764,7 @@ void AdornedRulerPanel::UpdatePrefs() { bool scrollBeyondZero = false; gPrefs->Read(wxT("/GUI/ScrollBeyondZero"), &scrollBeyondZero, false); - ruler.SetTwoTone(scrollBeyondZero); + mRuler.SetTwoTone(scrollBeyondZero); } #endif #endif @@ -1788,7 +1773,7 @@ void AdornedRulerPanel::UpdatePrefs() void AdornedRulerPanel::InvalidateRuler() { - ruler.Invalidate(); + mRuler.Invalidate(); } void AdornedRulerPanel::RegenerateTooltips() @@ -1819,24 +1804,23 @@ void AdornedRulerPanel::OnCapture(wxCommandEvent & evt) { // Set cursor immediately because OnMouseEvents is not called // if recording is initiated by a modal window (Timer Record). - SetCursor(wxCursor(wxCURSOR_DEFAULT)); + SetCursor(mCursorDefault); mIsRecording = true; } else { - SetCursor(wxCursor(wxCURSOR_HAND)); + SetCursor(mCursorHand); mIsRecording = false; } RegenerateTooltips(); } -void AdornedRulerPanel::OnErase(wxEraseEvent & WXUNUSED(evt)) -{ - // Ignore it to prevent flashing -} - void AdornedRulerPanel::OnPaint(wxPaintEvent & WXUNUSED(evt)) { - wxBufferedPaintDC dc(this); + wxSize sz = GetClientSize(); + wxPaintDC pdc(this); + wxBitmap buffer; + buffer.Create(sz.x, sz.y, pdc); + wxBufferedDC dc(&pdc, buffer); DoDrawBorder(&dc); @@ -1845,6 +1829,8 @@ void AdornedRulerPanel::OnPaint(wxPaintEvent & WXUNUSED(evt)) DoDrawSelection(&dc); } + DoDrawMarks(&dc, true); + if (mIndType >= 0) { DoDrawIndicator(&dc); @@ -1852,11 +1838,9 @@ void AdornedRulerPanel::OnPaint(wxPaintEvent & WXUNUSED(evt)) if (mQuickPlayInd) { - DrawQuickPlayIndicator(&dc, false); + DrawQuickPlayIndicator(&dc); } - DoDrawMarks(&dc, true); - if (mViewInfo->selectedRegion.isPoint()) { DoDrawCursor(&dc); @@ -1879,19 +1863,12 @@ void AdornedRulerPanel::OnSize(wxSizeEvent & WXUNUSED(evt)) mInner.width -= 2; // -2 for left and right bevels mInner.height -= 3; // -3 for top and bottom bevels and bottom line - ruler.SetBounds( mInner.GetLeft(), + mRuler.SetBounds(mInner.GetLeft(), mInner.GetTop(), mInner.GetRight(), - mInner.GetBottom() ); + mInner.GetBottom()); - if( mBuffer ) - { - delete mBuffer; - } - - mBuffer = new wxBitmap( mOuter.GetWidth(), mOuter.GetHeight() ); - - Refresh( false ); + Refresh(); } double AdornedRulerPanel::Pos2Time(int p, bool ignoreFisheye) @@ -1946,39 +1923,55 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) bool isWithinClick = (mLeftDownClick >= 0) && IsWithinMarker(mousePosX, mLeftDownClick); bool canDragSel = !mPlayRegionLock && mPlayRegionDragsSelection; - double t0 = mProject->GetTracks()->GetStartTime(); - double t1 = mProject->GetTracks()->GetEndTime(); + double t0 = mTracks->GetStartTime(); + double t1 = mTracks->GetEndTime(); double sel0 = mProject->GetSel0(); double sel1 = mProject->GetSel1(); mLastMouseX = mousePosX; mQuickPlayPos = Pos2Time(mousePosX); // If not looping, restrict selection to end of project - if (!evt.ShiftDown()) mQuickPlayPos = std::min(t1, mQuickPlayPos); - + if (!evt.ShiftDown()) { + mQuickPlayPos = std::min(t1, mQuickPlayPos); + } if (evt.Leaving()) { mQuickPlayInd = false; - wxClientDC cdc(this); - DrawQuickPlayIndicator(&cdc, true); - Refresh(false); + DrawQuickPlayIndicator(NULL); + Refresh(); + + SetCursor(mCursorDefault); + mIsWE = false; + + if (mSnapManager) { + delete mSnapManager; + mSnapManager = NULL; + } } else if (mQuickPlayEnabled) { mQuickPlayInd = true; - Refresh(false); + Refresh(); if (isWithinStart || isWithinEnd) { - SetCursor(wxCursor(wxCURSOR_SIZEWE)); + if (!mIsWE) { + SetCursor(mCursorSizeWE); + mIsWE = true; + } } else { - SetCursor(wxCursor(wxCURSOR_HAND)); + if (mIsWE) { + SetCursor(mCursorHand); + mIsWE = false; + } } } - else { - SetCursor(wxCursor(wxCURSOR_HAND)); + else if (evt.Entering()) { + SetCursor(mCursorHand); + mQuickPlayInd = false; + DrawQuickPlayIndicator(NULL); + Refresh(); } - if (evt.RightDown() && !(evt.LeftIsDown())) { ShowMenu(evt.GetPosition()); if (HasCapture()) @@ -2024,11 +2017,10 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) // Check if we are dragging BEFORE CaptureMouse. if (mMouseEventState != mesNone) - SetCursor(wxCursor(wxCURSOR_SIZEWE)); + SetCursor(mCursorSizeWE); CaptureMouse(); } - if (evt.LeftIsDown()) { switch (mMouseEventState) { @@ -2101,8 +2093,7 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) if (evt.LeftUp()) { mQuickPlayInd = false; - wxClientDC cdc(this); - DrawQuickPlayIndicator(&cdc, true); + DrawQuickPlayIndicator(NULL); if (HasCapture()) ReleaseMouse(); @@ -2180,7 +2171,7 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) mPlayRegionStart = start; mPlayRegionEnd = end; - DoDrawPlayRegion(&cdc); + Refresh(); } mMouseEventState = mesNone; @@ -2199,15 +2190,13 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt) void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt)) { - wxClientDC cdc(this); - DrawQuickPlayIndicator(&cdc, true); + DrawQuickPlayIndicator(NULL); wxMouseEvent e(wxEVT_LEFT_UP); e.m_x = mLastMouseX; OnMouseEvents(e); } - // Pop-up menu void AdornedRulerPanel::ShowMenu(const wxPoint & pos) @@ -2250,8 +2239,7 @@ void AdornedRulerPanel::ShowMenu(const wxPoint & pos) delete rulerMenu; // dismiss and clear Quick-Play indicator mQuickPlayInd = false; - wxClientDC cdc(this); - DrawQuickPlayIndicator(&cdc, true); + DrawQuickPlayIndicator(NULL); } void AdornedRulerPanel::OnToggleQuickPlay(wxCommandEvent&) @@ -2279,25 +2267,20 @@ void AdornedRulerPanel::DragSelection() mProject->SetSel0(mPlayRegionEnd); mProject->SetSel1(mPlayRegionStart); } - mProject->GetTrackPanel()->TrackPanel::DisplaySelection(); - mProject->GetTrackPanel()->TrackPanel::Refresh(false); + mProject->GetTrackPanel()->DisplaySelection(); + mProject->GetTrackPanel()->Refresh(false); } - void AdornedRulerPanel::HandleSnapping() { - if (mSnapManager) { - // Create a new snap manager in case any snap-points have changed - delete mSnapManager; + if (!mSnapManager) { + mSnapManager = new SnapManager(mTracks, mViewInfo); } - mSnapManager = new SnapManager(mProject->GetTracks(), NULL, NULL, - *mViewInfo, - QUICK_PLAY_SNAP_PIXEL); - bool snappedPoint, snappedTime; - mIsSnapped = (mSnapManager->Snap(NULL, mQuickPlayPos, false, - &mQuickPlayPos, &snappedPoint, &snappedTime)); -} + bool snappedPoint, snappedTime; + mIsSnapped = mSnapManager->Snap(NULL, mQuickPlayPos, false, + &mQuickPlayPos, &snappedPoint, &snappedTime); +} void AdornedRulerPanel::OnTimelineToolTips(wxCommandEvent&) { @@ -2309,7 +2292,6 @@ void AdornedRulerPanel::OnTimelineToolTips(wxCommandEvent&) #endif } - void AdornedRulerPanel::OnAutoScroll(wxCommandEvent&) { if (mViewInfo->bUpdateTrackIndicator) @@ -2412,14 +2394,14 @@ void AdornedRulerPanel::DoDrawMarks(wxDC * dc, bool /*text */ ) const double max = Pos2Time(mInner.width); const double hiddenMax = Pos2Time(mInner.width, true); - ruler.SetTickColour( theTheme.Colour( clrTrackPanelText ) ); - ruler.SetRange( min, max, hiddenMin, hiddenMax ); - ruler.Draw( *dc ); + mRuler.SetTickColour( theTheme.Colour( clrTrackPanelText ) ); + mRuler.SetRange( min, max, hiddenMin, hiddenMax ); + mRuler.Draw( *dc ); } void AdornedRulerPanel::DrawSelection() { - Refresh(false); + Refresh(); } void AdornedRulerPanel::DoDrawSelection(wxDC * dc) @@ -2442,14 +2424,14 @@ void AdornedRulerPanel::DoDrawSelection(wxDC * dc) void AdornedRulerPanel::SetLeftOffset(int offset) { mLeftOffset = offset; - ruler.SetUseZoomInfo(offset); + mRuler.SetUseZoomInfo(offset); } void AdornedRulerPanel::DrawCursor(double time) { mCurTime = time; - Refresh(false); + Refresh(); } void AdornedRulerPanel::DoDrawCursor(wxDC * dc) @@ -2468,7 +2450,7 @@ void AdornedRulerPanel::ClearIndicator() { mIndType = -1; - Refresh(false); + Refresh(); } void AdornedRulerPanel::DrawIndicator( double time, bool rec ) @@ -2483,16 +2465,12 @@ void AdornedRulerPanel::DrawIndicator( double time, bool rec ) mIndType = ( rec ? 0 : 1 ); - Refresh(false); + Refresh(); } // Draws the play/recording position indicator. void AdornedRulerPanel::DoDrawIndicator(wxDC * dc) { - if (mIndType < 0) { - return; - } - int indsize = 6; const int x = Time2Pos(mIndTime); @@ -2508,15 +2486,14 @@ void AdornedRulerPanel::DoDrawIndicator(wxDC * dc) dc->DrawPolygon( 3, tri ); } -// Draws the vertical line and green triangle indicating the Qick Play cursor position. -void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc, bool clear) +// Draws the vertical line and green triangle indicating the Quick Play cursor position. +void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc) { TrackPanel *tp = mProject->GetTrackPanel(); - wxClientDC cdc(tp); - double latestEnd = std::max(mProject->GetTracks()->GetEndTime(), mProject->GetSel1()); - if (clear || (mQuickPlayPos >= latestEnd)) { - tp->TrackPanel::DrawQuickPlayIndicator(cdc, -1); + double latestEnd = std::max(mTracks->GetEndTime(), mProject->GetSel1()); + if (dc == NULL || (mQuickPlayPos >= latestEnd)) { + tp->DrawQuickPlayIndicator(-1); return; } @@ -2534,7 +2511,7 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc, bool clear) AColor::IndicatorColor( dc, true); dc->DrawPolygon( 3, tri, x ); - tp->TrackPanel::DrawQuickPlayIndicator(cdc, x); + tp->DrawQuickPlayIndicator(x, mIsSnapped); } void AdornedRulerPanel::SetPlayRegion(double playRegionStart, @@ -2548,6 +2525,8 @@ void AdornedRulerPanel::SetPlayRegion(double playRegionStart, mPlayRegionStart = playRegionStart; mPlayRegionEnd = playRegionEnd; + + // Must use Refresh() Refresh(); } @@ -2559,6 +2538,8 @@ void AdornedRulerPanel::ClearPlayRegion() mPlayRegionStart = -1; mPlayRegionEnd = -1; mQuickPlayInd = false; + + // Must use Refresh() Refresh(); } @@ -2580,6 +2561,5 @@ void AdornedRulerPanel::GetPlayRegion(double* playRegionStart, void AdornedRulerPanel::GetMaxSize(wxCoord *width, wxCoord *height) { - ruler.GetMaxSize(width, height); + mRuler.GetMaxSize(width, height); } - diff --git a/src/widgets/Ruler.h b/src/widgets/Ruler.h index f33ad2e33..74e8495ad 100644 --- a/src/widgets/Ruler.h +++ b/src/widgets/Ruler.h @@ -23,6 +23,7 @@ class AudacityProject; class TimeTrack; class SnapManager; class NumberScale; +class TrackList; class AUDACITY_DLL_API Ruler { public: @@ -271,7 +272,7 @@ private: class AUDACITY_DLL_API AdornedRulerPanel : public wxPanel { public: - AdornedRulerPanel(wxWindow* parent, + AdornedRulerPanel(AudacityProject* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -300,11 +301,8 @@ public: void UpdatePrefs(); void RegenerateTooltips(); - bool mIsSnapped; - private: void OnCapture(wxCommandEvent & evt); - void OnErase(wxEraseEvent &evt); void OnPaint(wxPaintEvent &evt); void OnSize(wxSizeEvent &evt); void OnMouseEvents(wxMouseEvent &evt); @@ -315,7 +313,7 @@ private: void DoDrawCursor(wxDC * dc); void DoDrawSelection(wxDC * dc); void DoDrawIndicator(wxDC * dc); - void DrawQuickPlayIndicator(wxDC * dc, bool clear /*delete old only*/); + void DrawQuickPlayIndicator(wxDC * dc /*NULL to delete old only*/); void DoDrawPlayRegion(wxDC * dc); double Pos2Time(int p, bool ignoreFisheye = false); @@ -323,11 +321,17 @@ private: bool IsWithinMarker(int mousePosX, double markerTime); - Ruler ruler; +private: + + wxCursor mCursorDefault; + wxCursor mCursorHand; + wxCursor mCursorSizeWE; + bool mIsWE; + + Ruler mRuler; ViewInfo *mViewInfo; AudacityProject *mProject; - - wxBitmap *mBuffer; + TrackList *mTracks; wxRect mOuter; wxRect mInner; @@ -341,7 +345,9 @@ private: double mIndTime; bool mQuickPlayInd; double mQuickPlayPos; + SnapManager *mSnapManager; + bool mIsSnapped; bool mPlayRegionLock; double mPlayRegionStart; diff --git a/src/widgets/numformatter.cpp b/src/widgets/numformatter.cpp index 2c6dab828..792768c7a 100644 --- a/src/widgets/numformatter.cpp +++ b/src/widgets/numformatter.cpp @@ -114,13 +114,8 @@ wxString NumberFormatter::ToString(long val, int style) wxString NumberFormatter::ToString(wxLongLong_t val, int style) { -#if wxCHECK_VERSION(3,0,0) return PostProcessIntString(wxString::Format("%" wxLongLongFmtSpec "d", val), style); -#else - return PostProcessIntString(wxString::Format(wxT("%") wxLongLongFmtSpec wxT("d"), val), - style); -#endif } #endif // HAS_LONG_LONG_T_DIFFERENT_FROM_LONG