1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-07 07:57:43 +02:00

Mouseover highlight 1) MIDI buttons 2) other buttons 3) sliders...

... in Track Contol Panel.

Each of these three can be separately referted if we don't like it.

The first is independent of theme and does not use image files.

The second uses HiliteButtonExpand.png, which looks wrong in Classic theme, as
if that file was intended for Dark instead.

The third uses files SliderThumbHilited.png and SilderThumbRotatedHilited.png
as are also used to highlight other sliders in the toolbars.  The appearance
is distinguished only in Classic theme now.

Some cleanup of button drawing code is also done, removing a global variable,
and some change of arguments of other drawing functions is also done, to
make it easier to implement highlighting of other things in TrackPanel in a
way analogous to these.
This commit is contained in:
Paul Licameli 2017-07-09 12:35:47 -04:00
commit 2bdbea44e6
34 changed files with 378 additions and 215 deletions

View File

@ -3061,6 +3061,7 @@
5E3FFE701EC9032B0020F7C9 /* NoteTrackSliderHandles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NoteTrackSliderHandles.cpp; sourceTree = "<group>"; }; 5E3FFE701EC9032B0020F7C9 /* NoteTrackSliderHandles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NoteTrackSliderHandles.cpp; sourceTree = "<group>"; };
5E3FFE711EC9032B0020F7C9 /* NoteTrackSliderHandles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoteTrackSliderHandles.h; sourceTree = "<group>"; }; 5E3FFE711EC9032B0020F7C9 /* NoteTrackSliderHandles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoteTrackSliderHandles.h; sourceTree = "<group>"; };
5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = "<group>"; }; 5E4685F81CCA9D84008741F2 /* CommandFunctors.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandFunctors.h; sourceTree = "<group>"; };
5E52335F1EFDD57D001E4BB8 /* TrackPanelDrawingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelDrawingContext.h; sourceTree = "<group>"; };
5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = "<group>"; }; 5E61EE0C1CBAA6BB0009FCF1 /* MemoryX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryX.h; sourceTree = "<group>"; };
5E667A5E1F0BEE5F00C942A5 /* WaveTrackVZoomHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveTrackVZoomHandle.cpp; sourceTree = "<group>"; }; 5E667A5E1F0BEE5F00C942A5 /* WaveTrackVZoomHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WaveTrackVZoomHandle.cpp; sourceTree = "<group>"; };
5E667A5F1F0BEE5F00C942A5 /* WaveTrackVZoomHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveTrackVZoomHandle.h; sourceTree = "<group>"; }; 5E667A5F1F0BEE5F00C942A5 /* WaveTrackVZoomHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveTrackVZoomHandle.h; sourceTree = "<group>"; };
@ -4157,6 +4158,7 @@
1790B0EF09883BFD008A330A /* TrackPanelAx.h */, 1790B0EF09883BFD008A330A /* TrackPanelAx.h */,
5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */, 5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */,
5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */, 5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */,
5E52335F1EFDD57D001E4BB8 /* TrackPanelDrawingContext.h */,
2803C8B619F35AA000278526 /* TrackPanelListener.h */, 2803C8B619F35AA000278526 /* TrackPanelListener.h */,
5E15123A1DB000C000702E29 /* TrackPanelMouseEvent.h */, 5E15123A1DB000C000702E29 /* TrackPanelMouseEvent.h */,
5E7396611DAFDB1E00BA0A4D /* TrackPanelResizeHandle.h */, 5E7396611DAFDB1E00BA0A4D /* TrackPanelResizeHandle.h */,

View File

@ -230,10 +230,13 @@ void AColor::Bevel(wxDC & dc, bool up, const wxRect & r)
AColor::Line(dc, r.x, r.y + r.height, r.x + r.width, r.y + r.height); AColor::Line(dc, r.x, r.y + r.height, r.x + r.width, r.y + r.height);
} }
void AColor::Bevel2(wxDC & dc, bool up, const wxRect & r, bool bSel) void AColor::Bevel2
(wxDC & dc, bool up, const wxRect & r, bool bSel, bool bHighlight)
{ {
int index = 0; int index = 0;
if( bSel ) if ( bHighlight )
index = bmpHiliteButtonExpand;
else if( bSel )
index = up ? bmpUpButtonExpandSel : bmpDownButtonExpandSel; index = up ? bmpUpButtonExpandSel : bmpDownButtonExpandSel;
else else
index = up ? bmpUpButtonExpand : bmpDownButtonExpand; index = up ? bmpUpButtonExpand : bmpDownButtonExpand;

View File

@ -66,7 +66,8 @@ class AColor {
static void Line(wxDC & dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2); static void Line(wxDC & dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2);
static void DrawFocus(wxDC & dc, wxRect & r); static void DrawFocus(wxDC & dc, wxRect & r);
static void Bevel(wxDC & dc, bool up, const wxRect & r); static void Bevel(wxDC & dc, bool up, const wxRect & r);
static void Bevel2(wxDC & dc, bool up, const wxRect & r, bool bSel=false); static void Bevel2
(wxDC & dc, bool up, const wxRect & r, bool bSel=false, bool bHighlight = false);
static void BevelTrackInfo(wxDC & dc, bool up, const wxRect & r); static void BevelTrackInfo(wxDC & dc, bool up, const wxRect & r);
static wxColour Blend(const wxColour & c1, const wxColour & c2); static wxColour Blend(const wxColour & c1, const wxColour & c2);

View File

@ -311,11 +311,15 @@ static void DrawPoint(wxDC & dc, const wxRect & r, int x, int y, bool top)
} }
} }
#include "TrackPanelDrawingContext.h"
/// TODO: This should probably move to track artist. /// TODO: This should probably move to track artist.
void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, void Envelope::DrawPoints
bool dB, double dBRange, (TrackPanelDrawingContext &context, const wxRect & r, const ZoomInfo &zoomInfo,
float zoomMin, float zoomMax, bool mirrored) const bool dB, double dBRange,
float zoomMin, float zoomMax, bool mirrored) const
{ {
auto &dc = context.dc;
dc.SetPen(AColor::envelopePen); dc.SetPen(AColor::envelopePen);
dc.SetBrush(*wxWHITE_BRUSH); dc.SetBrush(*wxWHITE_BRUSH);

View File

@ -73,6 +73,7 @@ private:
}; };
typedef std::vector<EnvPoint> EnvArray; typedef std::vector<EnvPoint> EnvArray;
struct TrackPanelDrawingContext;
class Envelope final : public XMLTagHandler { class Envelope final : public XMLTagHandler {
public: public:
@ -117,7 +118,9 @@ public:
XMLTagHandler *HandleXMLChild(const wxChar *tag) override; XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
void WriteXML(XMLWriter &xmlFile) const /* not override */; void WriteXML(XMLWriter &xmlFile) const /* not override */;
void DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, void DrawPoints(
TrackPanelDrawingContext &context,
const wxRect & r, const ZoomInfo &zoomInfo,
bool dB, double dBRange, bool dB, double dBRange,
float zoomMin, float zoomMax, bool mirrored) const; float zoomMin, float zoomMax, bool mirrored) const;

View File

@ -773,13 +773,17 @@ namespace {
} }
} }
#include "TrackPanelDrawingContext.h"
/// Draw calls other functions to draw the LabelTrack. /// Draw calls other functions to draw the LabelTrack.
/// @param dc the device context /// @param dc the device context
/// @param r the LabelTrack rectangle. /// @param r the LabelTrack rectangle.
void LabelTrack::Draw(wxDC & dc, const wxRect & r, void LabelTrack::Draw
const SelectedRegion &selectedRegion, (TrackPanelDrawingContext &context, const wxRect & r,
const ZoomInfo &zoomInfo) const const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo) const
{ {
auto &dc = context.dc;
auto pHit = findHit(); auto pHit = findHit();
if(msFont.Ok()) if(msFont.Ok())

View File

@ -40,6 +40,7 @@ class ZoomInfo;
struct LabelTrackHit; struct LabelTrackHit;
struct TrackPanelDrawingContext;
class LabelStruct class LabelStruct
{ {
@ -147,7 +148,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track
static wxFont GetFont(const wxString &faceName, int size = DefaultFontSize); static wxFont GetFont(const wxString &faceName, int size = DefaultFontSize);
static void ResetFont(); static void ResetFont();
void Draw(wxDC & dc, const wxRect & r, void Draw(TrackPanelDrawingContext &context, const wxRect & r,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo) const; const ZoomInfo &zoomInfo) const;

View File

@ -247,6 +247,7 @@ audacity_SOURCES = \
TrackPanelAx.h \ TrackPanelAx.h \
TrackPanelCell.h \ TrackPanelCell.h \
TrackPanelCellIterator.h \ TrackPanelCellIterator.h \
TrackPanelDrawingContext.h \
TrackPanelListener.h \ TrackPanelListener.h \
TrackPanelMouseEvent.h \ TrackPanelMouseEvent.h \
TrackPanelResizeHandle.cpp \ TrackPanelResizeHandle.cpp \

View File

@ -328,7 +328,8 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \ TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \
TimeTrack.h Track.cpp Track.h TrackArtist.cpp TrackArtist.h \ TimeTrack.h Track.cpp Track.h TrackArtist.cpp TrackArtist.h \
TrackPanel.cpp TrackPanel.h TrackPanelAx.cpp TrackPanelAx.h \ TrackPanel.cpp TrackPanel.h TrackPanelAx.cpp TrackPanelAx.h \
TrackPanelCell.h TrackPanelCellIterator.h TrackPanelListener.h \ TrackPanelCell.h TrackPanelCellIterator.h \
TrackPanelDrawingContext.h TrackPanelListener.h \
TrackPanelMouseEvent.h TrackPanelResizeHandle.cpp \ TrackPanelMouseEvent.h TrackPanelResizeHandle.cpp \
TrackPanelResizeHandle.h TrackPanelResizerCell.cpp \ TrackPanelResizeHandle.h TrackPanelResizerCell.cpp \
TrackPanelResizerCell.h TranslatableStringArray.h UIHandle.h \ TrackPanelResizerCell.h TranslatableStringArray.h UIHandle.h \
@ -1342,7 +1343,8 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \
TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \ TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \
TimeTrack.h Track.cpp Track.h TrackArtist.cpp TrackArtist.h \ TimeTrack.h Track.cpp Track.h TrackArtist.cpp TrackArtist.h \
TrackPanel.cpp TrackPanel.h TrackPanelAx.cpp TrackPanelAx.h \ TrackPanel.cpp TrackPanel.h TrackPanelAx.cpp TrackPanelAx.h \
TrackPanelCell.h TrackPanelCellIterator.h TrackPanelListener.h \ TrackPanelCell.h TrackPanelCellIterator.h \
TrackPanelDrawingContext.h TrackPanelListener.h \
TrackPanelMouseEvent.h TrackPanelResizeHandle.cpp \ TrackPanelMouseEvent.h TrackPanelResizeHandle.cpp \
TrackPanelResizeHandle.h TrackPanelResizerCell.cpp \ TrackPanelResizeHandle.h TrackPanelResizerCell.cpp \
TrackPanelResizerCell.h TranslatableStringArray.h UIHandle.h \ TrackPanelResizerCell.h TranslatableStringArray.h UIHandle.h \

View File

@ -251,7 +251,7 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
// Draws the midi channel toggle buttons within the given rect. // Draws the midi channel toggle buttons within the given rect.
// The rect should be evenly divisible by 4 on both axis. // The rect should be evenly divisible by 4 on both axis.
void NoteTrack::DrawLabelControls void NoteTrack::DrawLabelControls
( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect ) ( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect, int highlightedChannel )
{ {
wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4"); wxASSERT_MSG(rect.width % 4 == 0, "Midi channel control rect width must be divisible by 4");
wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4"); wxASSERT_MSG(rect.height % 4 == 0, "Midi channel control rect height must be divisible by 4");
@ -273,7 +273,11 @@ void NoteTrack::DrawLabelControls
bool visible = pTrack ? pTrack->IsVisibleChan(chanName - 1) : true; bool visible = pTrack ? pTrack->IsVisibleChan(chanName - 1) : true;
if (visible) { if (visible) {
AColor::MIDIChannel(&dc, chanName); // highlightedChannel counts 0 based
if ( chanName == highlightedChannel + 1 )
AColor::LightMIDIChannel(&dc, chanName);
else
AColor::MIDIChannel(&dc, chanName);
dc.DrawRectangle(box); dc.DrawRectangle(box);
// two choices: channel is enabled (to see and play) when button is in // two choices: channel is enabled (to see and play) when button is in
// "up" position (original Audacity style) or in "down" position // "up" position (original Audacity style) or in "down" position
@ -299,7 +303,10 @@ void NoteTrack::DrawLabelControls
box.x, box.y + box.height - 1, box.x, box.y + box.height - 1,
box.x + box.width - 1, box.y + box.height - 1); box.x + box.width - 1, box.y + box.height - 1);
} else { } else {
AColor::MIDIChannel(&dc, 0); if ( chanName == highlightedChannel + 1 )
AColor::LightMIDIChannel(&dc, chanName);
else
AColor::MIDIChannel(&dc, 0);
dc.DrawRectangle(box); dc.DrawRectangle(box);
#if CHANNEL_ON_IS_DOWN #if CHANNEL_ON_IS_DOWN
AColor::LightMIDIChannel(&dc, 0); AColor::LightMIDIChannel(&dc, 0);

View File

@ -90,7 +90,8 @@ class AUDACITY_DLL_API NoteTrack final
const TimeWarper &warper, double semitones); const TimeWarper &warper, double semitones);
static void DrawLabelControls static void DrawLabelControls
( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect ); ( const NoteTrack *pTrack, wxDC & dc, const wxRect &rect,
int highlightedChannel = -1 );
int FindChannel(const wxRect &rect, int mx, int my); int FindChannel(const wxRect &rect, int mx, int my);
bool LabelClick(const wxRect &rect, int x, int y, bool right); bool LabelClick(const wxRect &rect, int x, int y, bool right);

View File

@ -32,6 +32,8 @@
#include "Experimental.h" #include "Experimental.h"
#include "TrackPanelDrawingContext.h"
// Globals, so that we remember settings from session to session // Globals, so that we remember settings from session to session
wxPrintData &gPrintData() wxPrintData &gPrintData()
{ {
@ -97,7 +99,9 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
r.width = width; r.width = width;
r.height = (int)(n->GetHeight() * scale); r.height = (int)(n->GetHeight() * scale);
artist.DrawTrack(n, *dc, r, SelectedRegion(), zoomInfo, false, false, false, false); TrackPanelDrawingContext context{ *dc, {}, {} };
artist.DrawTrack(
context, n, r, SelectedRegion(), zoomInfo, false, false, false, false);
dc->SetPen(*wxBLACK_PEN); dc->SetPen(*wxBLACK_PEN);
AColor::Line(*dc, 0, r.y, width, r.y); AColor::Line(*dc, 0, r.y, width, r.y);

View File

@ -257,8 +257,13 @@ void TimeTrack::WriteXML(XMLWriter &xmlFile) const
xmlFile.EndTag(wxT("timetrack")); xmlFile.EndTag(wxT("timetrack"));
} }
void TimeTrack::Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) const #include "TrackPanelDrawingContext.h"
void TimeTrack::Draw
(TrackPanelDrawingContext &context, const wxRect & r, const ZoomInfo &zoomInfo) const
{ {
auto &dc = context.dc;
double min = zoomInfo.PositionToTime(0); double min = zoomInfo.PositionToTime(0);
double max = zoomInfo.PositionToTime(r.width); double max = zoomInfo.PositionToTime(r.width);
if (min > max) if (min > max)

View File

@ -22,6 +22,7 @@ class wxDC;
class Envelope; class Envelope;
class Ruler; class Ruler;
class ZoomInfo; class ZoomInfo;
struct TrackPanelDrawingContext;
class EnvelopeHandle; class EnvelopeHandle;
@ -67,7 +68,9 @@ class TimeTrack final : public Track {
double GetStartTime() const override { return 0.0; } double GetStartTime() const override { return 0.0; }
double GetEndTime() const override { return 0.0; } double GetEndTime() const override { return 0.0; }
void Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) const; void Draw
(TrackPanelDrawingContext &context,
const wxRect & r, const ZoomInfo &zoomInfo) const;
// XMLTagHandler callback methods for loading and saving // XMLTagHandler callback methods for loading and saving

View File

@ -183,6 +183,8 @@ audio tracks.
#include "Theme.h" #include "Theme.h"
#include "AllThemeResources.h" #include "AllThemeResources.h"
#include "Experimental.h" #include "Experimental.h"
#include "TrackPanelDrawingContext.h"
#undef PROFILE_WAVEFORM #undef PROFILE_WAVEFORM
#ifdef PROFILE_WAVEFORM #ifdef PROFILE_WAVEFORM
@ -315,9 +317,9 @@ void TrackArtist::SetMargins(int left, int top, int right, int bottom)
mMarginBottom = bottom; mMarginBottom = bottom;
} }
void TrackArtist::DrawTracks(TrackList * tracks, void TrackArtist::DrawTracks(TrackPanelDrawingContext &context,
TrackList * tracks,
Track * start, Track * start,
wxDC & dc,
const wxRegion & reg, const wxRegion & reg,
const wxRect & rect, const wxRect & rect,
const wxRect & clip, const wxRect & clip,
@ -409,7 +411,7 @@ void TrackArtist::DrawTracks(TrackList * tracks,
rr.y += mMarginTop; rr.y += mMarginTop;
rr.width -= (mMarginLeft + mMarginRight); rr.width -= (mMarginLeft + mMarginRight);
rr.height -= (mMarginTop + mMarginBottom); rr.height -= (mMarginTop + mMarginBottom);
DrawTrack(t, dc, rr, DrawTrack(context, t, rr,
selectedRegion, zoomInfo, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawSliders, hasSolo); drawEnvelope, bigPoints, drawSliders, hasSolo);
} }
@ -438,8 +440,8 @@ void TrackArtist::DrawTracks(TrackList * tracks,
} }
} }
void TrackArtist::DrawTrack(const Track * t, void TrackArtist::DrawTrack(TrackPanelDrawingContext &context,
wxDC & dc, const Track * t,
const wxRect & rect, const wxRect & rect,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo, const ZoomInfo &zoomInfo,
@ -448,6 +450,7 @@ void TrackArtist::DrawTrack(const Track * t,
bool drawSliders, bool drawSliders,
bool hasSolo) bool hasSolo)
{ {
auto &dc = context.dc;
switch (t->GetKind()) { switch (t->GetKind()) {
case Track::Wave: case Track::Wave:
{ {
@ -466,7 +469,7 @@ void TrackArtist::DrawTrack(const Track * t,
switch (wt->GetDisplay()) { switch (wt->GetDisplay()) {
case WaveTrack::Waveform: case WaveTrack::Waveform:
DrawWaveform(wt, dc, rect, selectedRegion, zoomInfo, DrawWaveform(context, wt, rect, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawSliders, muted); drawEnvelope, bigPoints, drawSliders, muted);
break; break;
case WaveTrack::Spectrum: case WaveTrack::Spectrum:
@ -503,16 +506,18 @@ void TrackArtist::DrawTrack(const Track * t,
} }
#endif // USE_MIDI #endif // USE_MIDI
case Track::Label: case Track::Label:
DrawLabelTrack((LabelTrack *)t, dc, rect, selectedRegion, zoomInfo); DrawLabelTrack(context, (LabelTrack *)t, rect, selectedRegion, zoomInfo);
break; break;
case Track::Time: case Track::Time:
DrawTimeTrack((TimeTrack *)t, dc, rect, zoomInfo); DrawTimeTrack(context, (TimeTrack *)t, rect, zoomInfo);
break; break;
} }
} }
void TrackArtist::DrawVRuler(const Track *t, wxDC * dc, wxRect & rect) void TrackArtist::DrawVRuler
(TrackPanelDrawingContext &context, const Track *t, wxRect & rect)
{ {
auto dc = &context.dc;
int kind = t->GetKind(); int kind = t->GetKind();
// Label and Time tracks do not have a vruler // Label and Time tracks do not have a vruler
@ -1468,8 +1473,8 @@ void TrackArtist::DrawEnvLine(wxDC &dc, const wxRect &rect, int x0, int y0, int
} }
} }
void TrackArtist::DrawWaveform(const WaveTrack *track, void TrackArtist::DrawWaveform(TrackPanelDrawingContext &context,
wxDC & dc, const WaveTrack *track,
const wxRect & rect, const wxRect & rect,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo, const ZoomInfo &zoomInfo,
@ -1478,13 +1483,14 @@ void TrackArtist::DrawWaveform(const WaveTrack *track,
bool drawSliders, bool drawSliders,
bool muted) bool muted)
{ {
auto &dc = context.dc;
const bool dB = !track->GetWaveformSettings().isLinear(); const bool dB = !track->GetWaveformSettings().isLinear();
DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush, DrawBackgroundWithSelection(&dc, rect, track, blankSelectedBrush, blankBrush,
selectedRegion, zoomInfo); selectedRegion, zoomInfo);
for (const auto &clip: track->GetClips()) for (const auto &clip: track->GetClips())
DrawClipWaveform(track, clip.get(), dc, rect, selectedRegion, zoomInfo, DrawClipWaveform(context, track, clip.get(), rect, selectedRegion, zoomInfo,
drawEnvelope, bigPoints, drawEnvelope, bigPoints,
dB, muted); dB, muted);
@ -1737,9 +1743,9 @@ void FindWavePortions
} }
} }
void TrackArtist::DrawClipWaveform(const WaveTrack *track, void TrackArtist::DrawClipWaveform(TrackPanelDrawingContext &context,
const WaveTrack *track,
const WaveClip *clip, const WaveClip *clip,
wxDC & dc,
const wxRect & rect, const wxRect & rect,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo, const ZoomInfo &zoomInfo,
@ -1748,6 +1754,7 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
bool dB, bool dB,
bool muted) bool muted)
{ {
auto &dc = context.dc;
#ifdef PROFILE_WAVEFORM #ifdef PROFILE_WAVEFORM
Profiler profiler; Profiler profiler;
#endif #endif
@ -1954,7 +1961,8 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
if (drawEnvelope) { if (drawEnvelope) {
DrawEnvelope(dc, mid, env, zoomMin, zoomMax, dB, dBRange); DrawEnvelope(dc, mid, env, zoomMin, zoomMax, dB, dBRange);
clip->GetEnvelope()->DrawPoints(dc, rect, zoomInfo, dB, dBRange, zoomMin, zoomMax, true); clip->GetEnvelope()->DrawPoints
(context, rect, zoomInfo, dB, dBRange, zoomMin, zoomMax, true);
} }
// Draw arrows on the left side if the track extends to the left of the // Draw arrows on the left side if the track extends to the left of the
@ -3188,8 +3196,8 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track,
#endif // USE_MIDI #endif // USE_MIDI
void TrackArtist::DrawLabelTrack(const LabelTrack *track, void TrackArtist::DrawLabelTrack(TrackPanelDrawingContext &context,
wxDC & dc, const LabelTrack *track,
const wxRect & rect, const wxRect & rect,
const SelectedRegion &selectedRegion, const SelectedRegion &selectedRegion,
const ZoomInfo &zoomInfo) const ZoomInfo &zoomInfo)
@ -3200,15 +3208,15 @@ void TrackArtist::DrawLabelTrack(const LabelTrack *track,
if (!track->GetSelected() && !track->IsSyncLockSelected()) if (!track->GetSelected() && !track->IsSyncLockSelected())
sel0 = sel1 = 0.0; sel0 = sel1 = 0.0;
track->Draw(dc, rect, SelectedRegion(sel0, sel1), zoomInfo); track->Draw(context, rect, SelectedRegion(sel0, sel1), zoomInfo);
} }
void TrackArtist::DrawTimeTrack(const TimeTrack *track, void TrackArtist::DrawTimeTrack(TrackPanelDrawingContext &context,
wxDC & dc, const TimeTrack *track,
const wxRect & rect, const wxRect & rect,
const ZoomInfo &zoomInfo) const ZoomInfo &zoomInfo)
{ {
track->Draw(dc, rect, zoomInfo); track->Draw(context, rect, zoomInfo);
wxRect envRect = rect; wxRect envRect = rect;
envRect.height -= 2; envRect.height -= 2;
double lower = track->GetRangeLower(), upper = track->GetRangeUpper(); double lower = track->GetRangeLower(), upper = track->GetRangeUpper();
@ -3217,8 +3225,9 @@ void TrackArtist::DrawTimeTrack(const TimeTrack *track,
lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / mdBrange + 1.0; lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / mdBrange + 1.0;
upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / mdBrange + 1.0; upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / mdBrange + 1.0;
} }
track->GetEnvelope()->DrawPoints(dc, envRect, zoomInfo, track->GetEnvelope()->DrawPoints
track->GetDisplayLog(), mdBrange, lower, upper, false); (context, envRect, zoomInfo,
track->GetDisplayLog(), mdBrange, lower, upper, false);
} }
void TrackArtist::UpdatePrefs() void TrackArtist::UpdatePrefs()

View File

@ -41,6 +41,8 @@ class Ruler;
class SelectedRegion; class SelectedRegion;
class ZoomInfo; class ZoomInfo;
struct TrackPanelDrawingContext;
#ifndef uchar #ifndef uchar
typedef unsigned char uchar; typedef unsigned char uchar;
#endif #endif
@ -52,19 +54,22 @@ class AUDACITY_DLL_API TrackArtist {
~TrackArtist(); ~TrackArtist();
void SetColours(); void SetColours();
void DrawTracks(TrackList *tracks, Track *start, void DrawTracks(TrackPanelDrawingContext &context,
wxDC & dc, const wxRegion & reg, TrackList *tracks, Track *start,
const wxRegion & reg,
const wxRect & rect, const wxRect & clip, const wxRect & rect, const wxRect & clip,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo,
bool drawEnvelope, bool bigPoints, bool drawSliders); bool drawEnvelope, bool bigPoints, bool drawSliders);
void DrawTrack(const Track *t, void DrawTrack(TrackPanelDrawingContext &context,
wxDC & dc, const wxRect & rect, const Track *t,
const wxRect & rect,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo,
bool drawEnvelope, bool bigPoints, bool drawSliders, bool drawEnvelope, bool bigPoints, bool drawSliders,
bool hasSolo); bool hasSolo);
void DrawVRuler(const Track *t, wxDC *dc, wxRect & rect); void DrawVRuler(TrackPanelDrawingContext &context,
const Track *t, wxRect & rect);
void UpdateVRuler(const Track *t, wxRect & rect); void UpdateVRuler(const Track *t, wxRect & rect);
@ -94,8 +99,9 @@ class AUDACITY_DLL_API TrackArtist {
// Lower-level drawing functions // Lower-level drawing functions
// //
void DrawWaveform(const WaveTrack *track, void DrawWaveform(TrackPanelDrawingContext &context,
wxDC & dc, const wxRect & rect, const WaveTrack *track,
const wxRect & rect,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo,
bool drawEnvelope, bool bigPoints, bool drawSliders, bool drawEnvelope, bool bigPoints, bool drawSliders,
bool muted); bool muted);
@ -117,18 +123,21 @@ class AUDACITY_DLL_API TrackArtist {
bool muted); bool muted);
#endif // USE_MIDI #endif // USE_MIDI
void DrawLabelTrack(const LabelTrack *track, void DrawLabelTrack(TrackPanelDrawingContext &context,
wxDC & dc, const wxRect & rect, const LabelTrack *track,
const wxRect & rect,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo); const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo);
void DrawTimeTrack(const TimeTrack *track, void DrawTimeTrack(TrackPanelDrawingContext &context,
wxDC & dc, const wxRect & rect, const ZoomInfo &zoomInfo); const TimeTrack *track,
const wxRect & rect, const ZoomInfo &zoomInfo);
void DrawTimeSlider(wxDC & dc, const wxRect & rect, void DrawTimeSlider(wxDC & dc, const wxRect & rect,
bool rightwards); bool rightwards);
void DrawClipWaveform(const WaveTrack *track, const WaveClip *clip, void DrawClipWaveform(TrackPanelDrawingContext &context,
wxDC & dc, const wxRect & rect, const WaveTrack *track, const WaveClip *clip,
const wxRect & rect,
const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo, const SelectedRegion &selectedRegion, const ZoomInfo &zoomInfo,
bool drawEnvelope, bool bigPoints, bool drawEnvelope, bool bigPoints,
bool dB, bool muted); bool dB, bool muted);

View File

@ -1066,11 +1066,9 @@ void TrackPanel::OnContextMenu(wxContextMenuEvent & WXUNUSED(event))
struct TrackInfo::TCPLine { struct TrackInfo::TCPLine {
using DrawFunction = void (*)( using DrawFunction = void (*)(
wxDC *dc, TrackPanelDrawingContext &context,
const wxRect &rect, const wxRect &rect,
const Track *maybeNULL, const Track *maybeNULL
int pressed, // a value from MouseCaptureEnum; TODO: make it bool
bool captured
); );
unsigned items; // a bitwise OR of values of the enum above unsigned items; // a bitwise OR of values of the enum above
@ -1696,6 +1694,8 @@ void TrackPanel::Refresh(bool eraseBackground /* = TRUE */,
DisplaySelection(); DisplaySelection();
} }
#include "TrackPanelDrawingContext.h"
/// Draw the actual track areas. We only draw the borders /// Draw the actual track areas. We only draw the borders
/// and the little buttons and menues and whatnot here, the /// and the little buttons and menues and whatnot here, the
/// actual contents of each track are drawn by the TrackArtist. /// actual contents of each track are drawn by the TrackArtist.
@ -1718,26 +1718,28 @@ void TrackPanel::DrawTracks(wxDC * dc)
bool bigPointsFlag = pTtb->IsDown(drawTool) || bMultiToolDown; bool bigPointsFlag = pTtb->IsDown(drawTool) || bMultiToolDown;
bool sliderFlag = bMultiToolDown; bool sliderFlag = bMultiToolDown;
TrackPanelDrawingContext context{ *dc, Target(), mLastMouseState };
// The track artist actually draws the stuff inside each track // The track artist actually draws the stuff inside each track
auto first = GetProject()->GetFirstVisible(); auto first = GetProject()->GetFirstVisible();
mTrackArtist->DrawTracks(GetTracks(), first.get(), mTrackArtist->DrawTracks(context, GetTracks(), first.get(),
*dc, region, tracksRect, clip, region, tracksRect, clip,
mViewInfo->selectedRegion, *mViewInfo, mViewInfo->selectedRegion, *mViewInfo,
envelopeFlag, bigPointsFlag, sliderFlag); envelopeFlag, bigPointsFlag, sliderFlag);
DrawEverythingElse(dc, region, clip); DrawEverythingElse(context, region, clip);
} }
/// Draws 'Everything else'. In particular it draws: /// Draws 'Everything else'. In particular it draws:
/// - Drop shadow for tracks and vertical rulers. /// - Drop shadow for tracks and vertical rulers.
/// - Zooming Indicators. /// - Zooming Indicators.
/// - Fills in space below the tracks. /// - Fills in space below the tracks.
void TrackPanel::DrawEverythingElse(wxDC * dc, void TrackPanel::DrawEverythingElse(TrackPanelDrawingContext &context,
const wxRegion &region, const wxRegion &region,
const wxRect & clip) const wxRect & clip)
{ {
// We draw everything else // We draw everything else
auto dc = &context.dc;
wxRect focusRect(-1, -1, 0, 0); wxRect focusRect(-1, -1, 0, 0);
wxRect trackRect = clip; wxRect trackRect = clip;
trackRect.height = 0; // for drawing background in no tracks case. trackRect.height = 0; // for drawing background in no tracks case.
@ -1787,7 +1789,7 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
if (mAx->IsFocused(t)) { if (mAx->IsFocused(t)) {
focusRect = borderRect; focusRect = borderRect;
} }
DrawOutside(borderTrack, dc, borderRect); DrawOutside(context, borderTrack, borderRect);
} }
// Believe it or not, we can speed up redrawing if we don't // Believe it or not, we can speed up redrawing if we don't
@ -1806,7 +1808,7 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
rect.y += kTopMargin; rect.y += kTopMargin;
rect.width = GetVRulerWidth(); rect.width = GetVRulerWidth();
rect.height -= (kTopMargin + kBottomMargin); rect.height -= (kTopMargin + kBottomMargin);
mTrackArtist->DrawVRuler(t, dc, rect); mTrackArtist->DrawVRuler(context, t, rect);
} }
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
@ -1819,7 +1821,7 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
rect.y += kTopMargin; rect.y += kTopMargin;
rect.width = GetVRulerWidth(); rect.width = GetVRulerWidth();
rect.height -= (kTopMargin + kBottomMargin); rect.height -= (kTopMargin + kBottomMargin);
mTrackArtist->DrawVRuler(t, dc, rect); mTrackArtist->DrawVRuler(context, t, rect);
} }
} }
#endif #endif
@ -1856,20 +1858,21 @@ void TrackPanel::DrawEverythingElse(wxDC * dc,
#include "tracks/ui/TrackControls.h" #include "tracks/ui/TrackControls.h"
void TrackInfo::DrawItems void TrackInfo::DrawItems
( wxDC *dc, const wxRect &rect, const Track &track, ( TrackPanelDrawingContext &context,
int mouseCapture, bool captured ) const wxRect &rect, const Track &track )
{ {
const auto topLines = getTCPLines( track ); const auto topLines = getTCPLines( track );
const auto bottomLines = commonTrackTCPBottomLines; const auto bottomLines = commonTrackTCPBottomLines;
DrawItems DrawItems
( dc, rect, &track, topLines, bottomLines, mouseCapture, captured ); ( context, rect, &track, topLines, bottomLines );
} }
void TrackInfo::DrawItems void TrackInfo::DrawItems
( wxDC *dc, const wxRect &rect, const Track *pTrack, ( TrackPanelDrawingContext &context,
const std::vector<TCPLine> &topLines, const std::vector<TCPLine> &bottomLines, const wxRect &rect, const Track *pTrack,
int mouseCapture, bool captured ) const std::vector<TCPLine> &topLines, const std::vector<TCPLine> &bottomLines )
{ {
auto dc = &context.dc;
TrackInfo::SetTrackInfoFont(dc); TrackInfo::SetTrackInfoFont(dc);
dc->SetTextForeground(theTheme.Colour(clrTrackPanelText)); dc->SetTextForeground(theTheme.Colour(clrTrackPanelText));
@ -1882,7 +1885,7 @@ void TrackInfo::DrawItems
}; };
if ( !TrackInfo::HideTopItem( rect, itemRect ) && if ( !TrackInfo::HideTopItem( rect, itemRect ) &&
line.drawFunction ) line.drawFunction )
line.drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); line.drawFunction( context, itemRect, pTrack );
yy += line.height + line.extraSpace; yy += line.height + line.extraSpace;
} }
} }
@ -1895,21 +1898,27 @@ void TrackInfo::DrawItems
rect.x, rect.y + yy, rect.x, rect.y + yy,
rect.width, line.height rect.width, line.height
}; };
line.drawFunction( dc, itemRect, pTrack, mouseCapture, captured ); line.drawFunction( context, itemRect, pTrack );
} }
} }
} }
} }
#include "tracks/ui/TrackButtonHandles.h"
void TrackInfo::CloseTitleDrawFunction void TrackInfo::CloseTitleDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
bool selected = pTrack ? pTrack->GetSelected() : true; bool selected = pTrack ? pTrack->GetSelected() : true;
{ {
bool down = captured && (pressed == TrackPanel::IsClosing);
wxRect bev = rect; wxRect bev = rect;
GetCloseBoxHorizontalBounds( rect, bev ); GetCloseBoxHorizontalBounds( rect, bev );
AColor::Bevel2(*dc, !down, bev, selected ); auto target = dynamic_cast<CloseButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
AColor::Bevel2(*dc, !down, bev, selected, hit );
#ifdef EXPERIMENTAL_THEMING #ifdef EXPERIMENTAL_THEMING
wxPen pen( theTheme.Colour( clrTrackPanelText )); wxPen pen( theTheme.Colour( clrTrackPanelText ));
@ -1935,14 +1944,17 @@ void TrackInfo::CloseTitleDrawFunction
} }
{ {
wxRect bev = rect;
GetTitleBarHorizontalBounds( rect, bev );
auto target = dynamic_cast<MenuButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
wxString titleStr = wxString titleStr =
pTrack ? pTrack->GetName() : _("Name"); pTrack ? pTrack->GetName() : _("Name");
bool down = captured && (pressed == TrackPanel::IsPopping);
wxRect bev = rect;
GetTitleBarHorizontalBounds( rect, bev );
//bev.Inflate(-1, -1); //bev.Inflate(-1, -1);
AColor::Bevel2(*dc, !down, bev, selected); AColor::Bevel2(*dc, !down, bev, selected, hit);
// Draw title text // Draw title text
SetTrackInfoFont(dc); SetTrackInfoFont(dc);
@ -1993,21 +2005,26 @@ void TrackInfo::CloseTitleDrawFunction
} }
void TrackInfo::MinimizeSyncLockDrawFunction void TrackInfo::MinimizeSyncLockDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
bool selected = pTrack ? pTrack->GetSelected() : true; bool selected = pTrack ? pTrack->GetSelected() : true;
bool syncLockSelected = pTrack ? pTrack->IsSyncLockSelected() : true; bool syncLockSelected = pTrack ? pTrack->IsSyncLockSelected() : true;
bool minimized = pTrack ? pTrack->GetMinimized() : false; bool minimized = pTrack ? pTrack->GetMinimized() : false;
{ {
bool down = captured && (pressed == TrackPanel::IsMinimizing);
wxRect bev = rect; wxRect bev = rect;
GetMinimizeHorizontalBounds(rect, bev); GetMinimizeHorizontalBounds(rect, bev);
auto target = dynamic_cast<MinimizeButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
// Clear background to get rid of previous arrow // Clear background to get rid of previous arrow
//AColor::MediumTrackInfo(dc, t->GetSelected()); //AColor::MediumTrackInfo(dc, t->GetSelected());
//dc->DrawRectangle(bev); //dc->DrawRectangle(bev);
AColor::Bevel2(*dc, !down, bev, selected); AColor::Bevel2(*dc, !down, bev, selected, hit);
#ifdef EXPERIMENTAL_THEMING #ifdef EXPERIMENTAL_THEMING
wxColour c = theTheme.Colour(clrTrackPanelText); wxColour c = theTheme.Colour(clrTrackPanelText);
@ -2039,14 +2056,19 @@ void TrackInfo::MinimizeSyncLockDrawFunction
} }
} }
#include "tracks/playabletrack/notetrack/ui/NoteTrackButtonHandle.h"
void TrackInfo::MidiControlsDrawFunction void TrackInfo::MidiControlsDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
auto target = dynamic_cast<NoteTrackButtonHandle*>( context.target.get() );
auto channel = target ? target->GetChannel() : -1;
auto &dc = context.dc;
wxRect midiRect = rect; wxRect midiRect = rect;
GetMidiControlsHorizontalBounds(rect, midiRect); GetMidiControlsHorizontalBounds(rect, midiRect);
NoteTrack::DrawLabelControls NoteTrack::DrawLabelControls
( static_cast<const NoteTrack *>(pTrack), *dc, midiRect ); ( static_cast<const NoteTrack *>(pTrack), dc, midiRect, channel );
#endif // EXPERIMENTAL_MIDI_OUT #endif // EXPERIMENTAL_MIDI_OUT
} }
@ -2054,43 +2076,59 @@ template<typename TrackClass>
void TrackInfo::SliderDrawFunction void TrackInfo::SliderDrawFunction
( LWSlider *(*Selector) ( LWSlider *(*Selector)
(const wxRect &sliderRect, const TrackClass *t, bool captured, wxWindow*), (const wxRect &sliderRect, const TrackClass *t, bool captured, wxWindow*),
wxDC *dc, const wxRect &rect, const Track *pTrack, bool captured ) wxDC *dc, const wxRect &rect, const Track *pTrack,
bool captured, bool highlight )
{ {
wxRect sliderRect = rect; wxRect sliderRect = rect;
TrackInfo::GetSliderHorizontalBounds( rect.GetTopLeft(), sliderRect ); TrackInfo::GetSliderHorizontalBounds( rect.GetTopLeft(), sliderRect );
auto wt = static_cast<const TrackClass*>( pTrack ); auto wt = static_cast<const TrackClass*>( pTrack );
Selector( sliderRect, wt, captured, nullptr )->OnPaint(*dc, false); Selector( sliderRect, wt, captured, nullptr )->OnPaint(*dc, highlight);
} }
#include "tracks/playabletrack/wavetrack/ui/WaveTrackSliderHandles.h"
void TrackInfo::PanSliderDrawFunction void TrackInfo::PanSliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto target = dynamic_cast<PanSliderHandle*>( context.target.get() );
auto dc = &context.dc;
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
SliderDrawFunction<WaveTrack> SliderDrawFunction<WaveTrack>
( &TrackInfo::PanSlider, dc, rect, pTrack, captured); ( &TrackInfo::PanSlider, dc, rect, pTrack, captured, hit);
} }
void TrackInfo::GainSliderDrawFunction void TrackInfo::GainSliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto target = dynamic_cast<GainSliderHandle*>( context.target.get() );
auto dc = &context.dc;
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
SliderDrawFunction<WaveTrack> SliderDrawFunction<WaveTrack>
( &TrackInfo::GainSlider, dc, rect, pTrack, captured); ( &TrackInfo::GainSlider, dc, rect, pTrack, captured, hit);
} }
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
#include "tracks/playabletrack/notetrack/ui/NoteTrackSliderHandles.h"
void TrackInfo::VelocitySliderDrawFunction void TrackInfo::VelocitySliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
auto target = dynamic_cast<VelocitySliderHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
SliderDrawFunction<NoteTrack> SliderDrawFunction<NoteTrack>
( &TrackInfo::VelocitySlider, dc, rect, pTrack, captured); ( &TrackInfo::VelocitySlider, dc, rect, pTrack, captured, hit);
} }
#endif #endif
void TrackInfo::MuteOrSoloDrawFunction void TrackInfo::MuteOrSoloDrawFunction
( wxDC *dc, const wxRect &bev, const Track *pTrack, int pressed, bool captured, ( wxDC *dc, const wxRect &bev, const Track *pTrack, bool down, bool captured,
bool solo ) bool solo, bool hit )
{ {
bool down = captured &&
(pressed == ( solo ? TrackPanel::IsSoloing : TrackPanel::IsMuting ));
//bev.Inflate(-1, -1); //bev.Inflate(-1, -1);
bool selected = pTrack ? pTrack->GetSelected() : true; bool selected = pTrack ? pTrack->GetSelected() : true;
auto pt = dynamic_cast<const PlayableTrack *>(pTrack); auto pt = dynamic_cast<const PlayableTrack *>(pTrack);
@ -2129,7 +2167,7 @@ void TrackInfo::MuteOrSoloDrawFunction
*dc, *dc,
value == down, value == down,
bev, bev,
selected selected, hit
); );
SetTrackInfoFont(dc); SetTrackInfoFont(dc);
@ -2137,25 +2175,40 @@ void TrackInfo::MuteOrSoloDrawFunction
dc->DrawText(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);
} }
#include "tracks/playabletrack/ui/PlayableTrackButtonHandles.h"
void TrackInfo::WideMuteDrawFunction void TrackInfo::WideMuteDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
wxRect bev = rect; wxRect bev = rect;
GetWideMuteSoloHorizontalBounds( rect, bev ); GetWideMuteSoloHorizontalBounds( rect, bev );
MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, false ); auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
} }
void TrackInfo::WideSoloDrawFunction void TrackInfo::WideSoloDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
wxRect bev = rect; wxRect bev = rect;
GetWideMuteSoloHorizontalBounds( rect, bev ); GetWideMuteSoloHorizontalBounds( rect, bev );
MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, true ); auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
} }
void TrackInfo::MuteAndSoloDrawFunction void TrackInfo::MuteAndSoloDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, bool captured ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
bool bHasSoloButton = TrackPanel::HasSoloButton(); bool bHasSoloButton = TrackPanel::HasSoloButton();
wxRect bev = rect; wxRect bev = rect;
@ -2163,13 +2216,25 @@ void TrackInfo::MuteAndSoloDrawFunction
GetNarrowMuteHorizontalBounds( rect, bev ); GetNarrowMuteHorizontalBounds( rect, bev );
else else
GetWideMuteSoloHorizontalBounds( rect, bev ); GetWideMuteSoloHorizontalBounds( rect, bev );
MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, false ); {
auto target = dynamic_cast<MuteButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, false, hit );
}
if( !bHasSoloButton ) if( !bHasSoloButton )
return; return;
GetNarrowSoloHorizontalBounds( rect, bev ); GetNarrowSoloHorizontalBounds( rect, bev );
MuteOrSoloDrawFunction( dc, bev, pTrack, pressed, captured, true ); {
auto target = dynamic_cast<SoloButtonHandle*>( context.target.get() );
bool hit = target && target->GetTrack().get() == pTrack;
bool captured = hit && target->IsClicked();
bool down = captured && bev.Contains( context.lastState.GetPosition());
MuteOrSoloDrawFunction( dc, bev, pTrack, down, captured, true, hit );
}
} }
void TrackInfo::StatusDrawFunction void TrackInfo::StatusDrawFunction
@ -2180,8 +2245,10 @@ void TrackInfo::StatusDrawFunction
} }
void TrackInfo::Status1DrawFunction void TrackInfo::Status1DrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
auto wt = static_cast<const WaveTrack*>(pTrack); auto wt = static_cast<const WaveTrack*>(pTrack);
/// Returns the string to be displayed in the track label /// Returns the string to be displayed in the track label
@ -2208,23 +2275,28 @@ void TrackInfo::Status1DrawFunction
} }
void TrackInfo::Status2DrawFunction void TrackInfo::Status2DrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int, bool ) ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack )
{ {
auto dc = &context.dc;
auto wt = static_cast<const WaveTrack*>(pTrack); auto wt = static_cast<const WaveTrack*>(pTrack);
auto format = wt ? wt->GetSampleFormat() : floatSample; auto format = wt ? wt->GetSampleFormat() : floatSample;
auto s = GetSampleFormatStr(format); auto s = GetSampleFormatStr(format);
StatusDrawFunction( s, dc, rect ); StatusDrawFunction( s, dc, rect );
} }
void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec) void TrackPanel::DrawOutside
(TrackPanelDrawingContext &context,
Track * t, const wxRect & rec)
{ {
auto dc = &context.dc;
bool bIsWave = (t->GetKind() == Track::Wave); bool bIsWave = (t->GetKind() == Track::Wave);
// Draw things that extend right of track control panel // Draw things that extend right of track control panel
{ {
// Start with whole track rect // Start with whole track rect
wxRect rect = rec; wxRect rect = rec;
DrawOutsideOfTrack(t, dc, rect); DrawOutsideOfTrack(context, t, rect);
// Now exclude left, right, and top insets // Now exclude left, right, and top insets
rect.x += kLeftInset; rect.x += kLeftInset;
@ -2256,16 +2328,7 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec)
rect.y += kTopMargin; rect.y += kTopMargin;
rect.height -= (kBottomMargin + kTopMargin); rect.height -= (kBottomMargin + kTopMargin);
// Need to know which button, if any, to draw as pressed. TrackInfo::DrawItems( context, rect, *t );
const MouseCaptureEnum mouseCapture =
// This public global variable is a hack for now, which should go away
// when TrackPanelCell gets a virtual function into which we move this
// drawing code.
MouseCaptureEnum(TrackControls::gCaptureState);
auto pClickedTrack = GetTracks()->Lock(mpClickedTrack);
const bool captured = (t == pClickedTrack.get());
TrackInfo::DrawItems( dc, rect, *t, mouseCapture, captured );
//mTrackInfo.DrawBordersWithin( dc, rect, *t ); //mTrackInfo.DrawBordersWithin( dc, rect, *t );
} }
@ -2274,8 +2337,11 @@ void TrackPanel::DrawOutside(Track * t, wxDC * dc, const wxRect & rec)
// Paint the inset areas left, top, and right in a background color // Paint the inset areas left, top, and right in a background color
// If linked to a following channel, also paint the separator area, which // If linked to a following channel, also paint the separator area, which
// overlaps the next track rectangle's top // overlaps the next track rectangle's top
void TrackPanel::DrawOutsideOfTrack(Track * t, wxDC * dc, const wxRect & rect) void TrackPanel::DrawOutsideOfTrack
(TrackPanelDrawingContext &context, Track * t, const wxRect & rect)
{ {
auto dc = &context.dc;
// Fill in area outside of the track // Fill in area outside of the track
AColor::TrackPanelBackground(dc, false); AColor::TrackPanelBackground(dc, false);
wxRect side; wxRect side;

View File

@ -61,6 +61,8 @@ using UIHandlePtr = std::shared_ptr<UIHandle>;
// Declared elsewhere, to reduce compilation dependencies // Declared elsewhere, to reduce compilation dependencies
class TrackPanelListener; class TrackPanelListener;
struct TrackPanelDrawingContext;
enum class UndoPush : unsigned char; enum class UndoPush : unsigned char;
// JKC Nov 2011: Disabled warning C4251 which is to do with DLL linkage // JKC Nov 2011: Disabled warning C4251 which is to do with DLL linkage
@ -93,74 +95,75 @@ public:
struct TCPLine; struct TCPLine;
static void DrawItems static void DrawItems
( wxDC *dc, const wxRect &rect, const Track &track, int mouseCapture, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track &track );
static void DrawItems static void DrawItems
( wxDC *dc, const wxRect &rect, const Track *pTrack, ( TrackPanelDrawingContext &context,
const wxRect &rect, const Track *pTrack,
const std::vector<TCPLine> &topLines, const std::vector<TCPLine> &topLines,
const std::vector<TCPLine> &bottomLines, const std::vector<TCPLine> &bottomLines );
int mouseCapture, bool captured );
static void CloseTitleDrawFunction static void CloseTitleDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void MinimizeSyncLockDrawFunction static void MinimizeSyncLockDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void MidiControlsDrawFunction static void MidiControlsDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
template<typename TrackClass> template<typename TrackClass>
static void SliderDrawFunction static void SliderDrawFunction
( LWSlider *(*Selector) ( LWSlider *(*Selector)
(const wxRect &sliderRect, const TrackClass *t, bool captured, (const wxRect &sliderRect, const TrackClass *t, bool captured,
wxWindow*), wxWindow*),
wxDC *dc, const wxRect &rect, const Track *pTrack, bool captured ); wxDC *dc, const wxRect &rect, const Track *pTrack,
bool captured, bool highlight );
static void PanSliderDrawFunction static void PanSliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void GainSliderDrawFunction static void GainSliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
#ifdef EXPERIMENTAL_MIDI_OUT #ifdef EXPERIMENTAL_MIDI_OUT
static void VelocitySliderDrawFunction static void VelocitySliderDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
#endif #endif
static void MuteOrSoloDrawFunction static void MuteOrSoloDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( wxDC *dc, const wxRect &rect, const Track *pTrack, bool down,
bool captured, bool solo ); bool captured, bool solo, bool hit );
static void WideMuteDrawFunction static void WideMuteDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void WideSoloDrawFunction static void WideSoloDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void MuteAndSoloDrawFunction static void MuteAndSoloDrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void StatusDrawFunction static void StatusDrawFunction
( const wxString &string, wxDC *dc, const wxRect &rect ); ( const wxString &string, wxDC *dc, const wxRect &rect );
static void Status1DrawFunction static void Status1DrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
static void Status2DrawFunction static void Status2DrawFunction
( wxDC *dc, const wxRect &rect, const Track *pTrack, int pressed, ( TrackPanelDrawingContext &context,
bool captured ); const wxRect &rect, const Track *pTrack );
public: public:
int GetTrackInfoWidth() const; int GetTrackInfoWidth() const;
@ -169,7 +172,6 @@ public:
void DrawBackground(wxDC * dc, const wxRect & rect, bool bSelected, bool bHasMuteSolo, const int labelw, const int vrul) const; void DrawBackground(wxDC * dc, const wxRect & rect, bool bSelected, bool bHasMuteSolo, const int labelw, const int vrul) const;
void DrawBordersWithin(wxDC * dc, const wxRect & rect, const Track &track ) const; void DrawBordersWithin(wxDC * dc, const wxRect & rect, const Track &track ) const;
void DrawVRuler(wxDC * dc, const wxRect & rect, Track * t) const;
static void GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest ); static void GetCloseBoxHorizontalBounds( const wxRect & rect, wxRect &dest );
static void GetCloseBoxRect(const wxRect & rect, wxRect &dest); static void GetCloseBoxRect(const wxRect & rect, wxRect &dest);
@ -410,14 +412,19 @@ public:
protected: protected:
void DrawTracks(wxDC * dc); void DrawTracks(wxDC * dc);
void DrawEverythingElse(wxDC *dc, const wxRegion & region, void DrawEverythingElse(TrackPanelDrawingContext &context,
const wxRegion & region,
const wxRect & clip); const wxRect & clip);
void DrawOutside(Track *t, wxDC *dc, const wxRect & rec); void DrawOutside
(TrackPanelDrawingContext &context,
Track *t, const wxRect & rec);
void HighlightFocusedTrack (wxDC* dc, const wxRect &rect); void HighlightFocusedTrack (wxDC* dc, const wxRect &rect);
void DrawShadow (Track *t, wxDC* dc, const wxRect & rect); void DrawShadow (Track *t, wxDC* dc, const wxRect & rect);
void DrawBordersAroundTrack(Track *t, wxDC* dc, const wxRect & rect, const int labelw, const int vrul); void DrawBordersAroundTrack(Track *t, wxDC* dc, const wxRect & rect, const int labelw, const int vrul);
void DrawOutsideOfTrack (Track *t, wxDC* dc, const wxRect & rect); void DrawOutsideOfTrack
(TrackPanelDrawingContext &context,
Track *t, const wxRect & rect);
public: public:
// Set the object that performs catch-all event handling when the pointer // Set the object that performs catch-all event handling when the pointer
@ -492,20 +499,6 @@ protected:
int mMouseMostRecentX; int mMouseMostRecentX;
int mMouseMostRecentY; int mMouseMostRecentY;
public:
// Old enumeration of click-and-drag states, which will shrink and disappear
// as UIHandle subclasses take over the repsonsibilities.
enum MouseCaptureEnum
{
IsUncaptured = 0,
IsClosing,
IsMuting,
IsSoloing,
IsMinimizing,
IsPopping,
};
protected:
friend class TrackPanelAx; friend class TrackPanelAx;
#if wxUSE_ACCESSIBILITY #if wxUSE_ACCESSIBILITY

View File

@ -0,0 +1,28 @@
/**********************************************************************
Audacity: A Digital Audio Editor
TrackPanelDrawingContext.h
Paul Licameli
**********************************************************************/
#ifndef __AUDACITY_TRACK_PANEL_DRAWING_CONTEXT__
#define __AUDACITY_TRACK_PANEL_DRAWING_CONTEXT__
#include "MemoryX.h"
class UIHandle;
using UIHandlePtr = std::shared_ptr<UIHandle>;
class wxDC;
#include <wx/mousestate.h>
struct TrackPanelDrawingContext {
wxDC &dc;
UIHandlePtr target;
wxMouseState lastState;
};
#endif

View File

@ -2871,6 +2871,7 @@ void EqualizationPanel::OnSize(wxSizeEvent & WXUNUSED(event))
Refresh( false ); Refresh( false );
} }
#include "TrackPanelDrawingContext.h"
void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
{ {
wxPaintDC dc(this); wxPaintDC dc(this);
@ -3038,8 +3039,10 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
memDC.SetPen(*wxBLACK_PEN); memDC.SetPen(*wxBLACK_PEN);
if( mEffect->mDraw->GetValue() ) if( mEffect->mDraw->GetValue() )
{ {
mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, ZoomInfo(0.0, mEnvRect.width-1), false, 0.0, TrackPanelDrawingContext context{ memDC, {}, {} };
mEffect->mdBMin, mEffect->mdBMax, false); mEffect->mEnvelope->DrawPoints(
context, mEnvRect, ZoomInfo(0.0, mEnvRect.width-1), false, 0.0,
mEffect->mdBMin, mEffect->mdBMax, false);
} }
dc.Blit(0, 0, mWidth, mHeight, &memDC, 0, 0, wxCOPY, FALSE); dc.Blit(0, 0, mWidth, mHeight, &memDC, 0, 0, wxCOPY, FALSE);

View File

@ -24,12 +24,23 @@ NoteTrackButtonHandle::NoteTrackButtonHandle
: mpTrack{ pTrack } : mpTrack{ pTrack }
, mChannel{ channel } , mChannel{ channel }
, mRect{ rect } , mRect{ rect }
{} {
mChangeHighlight = RefreshCode::RefreshCell;
}
NoteTrackButtonHandle::~NoteTrackButtonHandle() NoteTrackButtonHandle::~NoteTrackButtonHandle()
{ {
} }
UIHandle::Result NoteTrackButtonHandle::NeedChangeHighlight
(const NoteTrackButtonHandle &oldState, const NoteTrackButtonHandle &newState)
{
if (oldState.GetChannel() != newState.GetChannel())
// Repaint whenever the highlighted button is different
return RefreshCode::RefreshCell;
return 0;
}
UIHandlePtr NoteTrackButtonHandle::HitTest UIHandlePtr NoteTrackButtonHandle::HitTest
(std::weak_ptr<NoteTrackButtonHandle> &holder, (std::weak_ptr<NoteTrackButtonHandle> &holder,
const wxMouseState &state, const wxRect &rect, const wxMouseState &state, const wxRect &rect,

View File

@ -42,6 +42,10 @@ public:
int GetChannel() const { return mChannel; } int GetChannel() const { return mChannel; }
static UIHandle::Result NeedChangeHighlight
(const NoteTrackButtonHandle &oldState,
const NoteTrackButtonHandle &newState);
protected: protected:
Result Click Result Click
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override; (const TrackPanelMouseEvent &event, AudacityProject *pProject) override;

View File

@ -20,7 +20,7 @@ Paul Licameli split from TrackPanel.cpp
MuteButtonHandle::MuteButtonHandle MuteButtonHandle::MuteButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect ) ( const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: ButtonHandle{ pTrack, rect, TrackPanel::IsMuting } : ButtonHandle{ pTrack, rect }
{} {}
MuteButtonHandle::~MuteButtonHandle() MuteButtonHandle::~MuteButtonHandle()
@ -62,7 +62,7 @@ UIHandlePtr MuteButtonHandle::HitTest
SoloButtonHandle::SoloButtonHandle SoloButtonHandle::SoloButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect ) ( const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: ButtonHandle{ pTrack, rect, TrackPanel::IsSoloing } : ButtonHandle{ pTrack, rect }
{} {}
SoloButtonHandle::~SoloButtonHandle() SoloButtonHandle::~SoloButtonHandle()

View File

@ -12,8 +12,6 @@ Paul Licameli split from TrackPanel.cpp
#define __AUDACITY_PLAYABLE_TRACK_BUTTON_HANDLES__ #define __AUDACITY_PLAYABLE_TRACK_BUTTON_HANDLES__
#include "../../ui/ButtonHandle.h" #include "../../ui/ButtonHandle.h"
#include "../../../TrackPanel.h"
class wxMouseState; class wxMouseState;
class MuteButtonHandle final : public ButtonHandle class MuteButtonHandle final : public ButtonHandle
@ -50,7 +48,7 @@ class SoloButtonHandle final : public ButtonHandle
public: public:
explicit SoloButtonHandle explicit SoloButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect ); ( const std::shared_ptr<Track> &pTrack, const wxRect &rect );
SoloButtonHandle &operator=(const SoloButtonHandle&) = default; SoloButtonHandle &operator=(const SoloButtonHandle&) = default;

View File

@ -21,11 +21,12 @@ Paul Licameli
#include "../ui/TrackControls.h" #include "../ui/TrackControls.h"
ButtonHandle::ButtonHandle ButtonHandle::ButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect, int dragCode ) ( const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: mpTrack{ pTrack } : mpTrack{ pTrack }
, mRect{ rect } , mRect{ rect }
, mDragCode{ dragCode } {
{} mChangeHighlight = RefreshCode::RefreshCell;
}
ButtonHandle::~ButtonHandle() ButtonHandle::~ButtonHandle()
{ {
@ -45,7 +46,8 @@ UIHandle::Result ButtonHandle::Click
// Come here for left click or double click // Come here for left click or double click
if (mRect.Contains(event.m_x, event.m_y)) { if (mRect.Contains(event.m_x, event.m_y)) {
TrackControls::gCaptureState = mDragCode; mWasIn = true;
mIsClicked = true;
// Toggle visible button state // Toggle visible button state
return RefreshCell; return RefreshCell;
} }
@ -62,14 +64,10 @@ UIHandle::Result ButtonHandle::Drag
if (!pTrack) if (!pTrack)
return Cancelled; return Cancelled;
const int newState = auto isIn = mRect.Contains(event.m_x, event.m_y);
mRect.Contains(event.m_x, event.m_y) ? mDragCode : 0; auto result = (isIn == mWasIn) ? RefreshNone : RefreshCell;
if (TrackControls::gCaptureState == newState) mWasIn = isIn;
return RefreshNone; return result;
else {
TrackControls::gCaptureState = newState;
return RefreshCell;
}
} }
HitTestPreview ButtonHandle::Preview HitTestPreview ButtonHandle::Preview
@ -90,22 +88,13 @@ UIHandle::Result ButtonHandle::Release
Result result = RefreshNone; Result result = RefreshNone;
const wxMouseEvent &event = evt.event; const wxMouseEvent &event = evt.event;
if (TrackControls::gCaptureState) {
TrackControls::gCaptureState = 0;
result = RefreshCell;
}
if (pTrack && mRect.Contains(event.m_x, event.m_y)) if (pTrack && mRect.Contains(event.m_x, event.m_y))
result |= CommitChanges(event, pProject, pParent); result |= RefreshCell | CommitChanges(event, pProject, pParent);
return result; return result;
} }
UIHandle::Result ButtonHandle::Cancel(AudacityProject *pProject) UIHandle::Result ButtonHandle::Cancel(AudacityProject *pProject)
{ {
using namespace RefreshCode; using namespace RefreshCode;
if (TrackControls::gCaptureState) { return RefreshCell; // perhaps unnecessarily if pointer is out of the box
TrackControls::gCaptureState = 0;
return RefreshCell;
}
else
return RefreshNone;
} }

View File

@ -23,9 +23,13 @@ class ButtonHandle /* not final */ : public UIHandle
{ {
ButtonHandle(const ButtonHandle&) = delete; ButtonHandle(const ButtonHandle&) = delete;
public:
std::shared_ptr<Track> GetTrack() const { return mpTrack.lock(); }
bool IsClicked() const { return mIsClicked; }
protected: protected:
explicit ButtonHandle explicit ButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect, int dragCode ); ( const std::shared_ptr<Track> &pTrack, const wxRect &rect );
ButtonHandle &operator=(const ButtonHandle&) = default; ButtonHandle &operator=(const ButtonHandle&) = default;
@ -56,7 +60,8 @@ protected:
std::weak_ptr<Track> mpTrack; std::weak_ptr<Track> mpTrack;
wxRect mRect; wxRect mRect;
int mDragCode; bool mWasIn{ true };
bool mIsClicked{};
}; };
#endif #endif

View File

@ -21,7 +21,9 @@ SliderHandle::SliderHandle
: mSliderFn{ sliderFn } : mSliderFn{ sliderFn }
, mRect{ rect } , mRect{ rect }
, mpTrack{ pTrack } , mpTrack{ pTrack }
{} {
mChangeHighlight = RefreshCode::RefreshCell;
}
SliderHandle::~SliderHandle() SliderHandle::~SliderHandle()
{ {
@ -44,8 +46,10 @@ UIHandle::Result SliderHandle::Click
// Just did a modal dialog in OnMouseEvent // Just did a modal dialog in OnMouseEvent
// Do not start a drag // Do not start a drag
return RefreshCell | Cancelled; return RefreshCell | Cancelled;
else else {
mIsClicked = true;
return RefreshCell; return RefreshCell;
}
} }
UIHandle::Result SliderHandle::Drag UIHandle::Result SliderHandle::Drag

View File

@ -32,6 +32,9 @@ public:
SliderHandle &operator=(const SliderHandle&) = default; SliderHandle &operator=(const SliderHandle&) = default;
std::shared_ptr<Track> GetTrack() const { return mpTrack.lock(); }
bool IsClicked() const { return mIsClicked; }
protected: protected:
virtual ~SliderHandle(); virtual ~SliderHandle();
@ -67,6 +70,8 @@ protected:
LWSlider *GetSlider( AudacityProject *pProject ); LWSlider *GetSlider( AudacityProject *pProject );
float mStartingValue {}; float mStartingValue {};
bool mIsClicked{};
}; };
#endif #endif

View File

@ -19,7 +19,7 @@ Paul Licameli split from TrackPanel.cpp
MinimizeButtonHandle::MinimizeButtonHandle MinimizeButtonHandle::MinimizeButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect ) ( const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: ButtonHandle{ pTrack, rect, TrackPanel::IsMinimizing } : ButtonHandle{ pTrack, rect }
{} {}
MinimizeButtonHandle::~MinimizeButtonHandle() MinimizeButtonHandle::~MinimizeButtonHandle()
@ -69,7 +69,7 @@ UIHandlePtr MinimizeButtonHandle::HitTest
CloseButtonHandle::CloseButtonHandle CloseButtonHandle::CloseButtonHandle
( const std::shared_ptr<Track> &pTrack, const wxRect &rect ) ( const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: ButtonHandle{ pTrack, rect, TrackPanel::IsClosing } : ButtonHandle{ pTrack, rect }
{} {}
CloseButtonHandle::~CloseButtonHandle() CloseButtonHandle::~CloseButtonHandle()
@ -121,7 +121,7 @@ UIHandlePtr CloseButtonHandle::HitTest
MenuButtonHandle::MenuButtonHandle MenuButtonHandle::MenuButtonHandle
( const std::shared_ptr<TrackPanelCell> &pCell, ( const std::shared_ptr<TrackPanelCell> &pCell,
const std::shared_ptr<Track> &pTrack, const wxRect &rect ) const std::shared_ptr<Track> &pTrack, const wxRect &rect )
: ButtonHandle{ pTrack, rect, TrackPanel::IsPopping } : ButtonHandle{ pTrack, rect }
, mpCell{ pCell } , mpCell{ pCell }
{} {}

View File

@ -12,7 +12,6 @@ Paul Licameli split from TrackPanel.cpp
#define __AUDACITY_TRACK_BUTTON_HANDLES__ #define __AUDACITY_TRACK_BUTTON_HANDLES__
#include "../ui/ButtonHandle.h" #include "../ui/ButtonHandle.h"
#include "../../TrackPanel.h"
class wxMouseState; class wxMouseState;

View File

@ -21,8 +21,6 @@ Paul Licameli split from TrackPanel.cpp
#include "../../Track.h" #include "../../Track.h"
#include <wx/textdlg.h> #include <wx/textdlg.h>
int TrackControls::gCaptureState;
TrackControls::TrackControls( std::shared_ptr<Track> pTrack ) TrackControls::TrackControls( std::shared_ptr<Track> pTrack )
: mwTrack{ pTrack } : mwTrack{ pTrack }
{ {

View File

@ -42,9 +42,6 @@ public:
unsigned result; unsigned result;
}; };
// Make this hack go away! See TrackPanel::DrawOutside
static int gCaptureState;
protected: protected:
// An override is supplied for derived classes to call through but it is // An override is supplied for derived classes to call through but it is
// still marked pure virtual // still marked pure virtual

View File

@ -508,6 +508,7 @@
<ClInclude Include="..\..\..\src\toolbars\SpectralSelectionBarListener.h" /> <ClInclude Include="..\..\..\src\toolbars\SpectralSelectionBarListener.h" />
<ClInclude Include="..\..\..\src\TrackPanelCell.h" /> <ClInclude Include="..\..\..\src\TrackPanelCell.h" />
<ClInclude Include="..\..\..\src\TrackPanelCellIterator.h" /> <ClInclude Include="..\..\..\src\TrackPanelCellIterator.h" />
<ClInclude Include="..\..\..\src\TrackPanelDrawingContext.h" />
<ClInclude Include="..\..\..\src\TrackPanelListener.h" /> <ClInclude Include="..\..\..\src\TrackPanelListener.h" />
<ClInclude Include="..\..\..\src\TrackPanelMouseEvent.h" /> <ClInclude Include="..\..\..\src\TrackPanelMouseEvent.h" />
<ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackButtonHandle.h" /> <ClInclude Include="..\..\..\src\tracks\playabletrack\notetrack\ui\NoteTrackButtonHandle.h" />

View File

@ -1933,6 +1933,9 @@
<ClInclude Include="..\..\..\src\RealFFTf48x.h"> <ClInclude Include="..\..\..\src\RealFFTf48x.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\TrackPanelDrawingContext.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\TrackPanelCell.h"> <ClInclude Include="..\..\..\src\TrackPanelCell.h">
<Filter>src</Filter> <Filter>src</Filter>
</ClInclude> </ClInclude>