1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-05 14:49:25 +02:00

Move track resizing code out of TrackPanel.cpp, though it still...

... cooperates more closely with TrackPanel than the other UIHandle subclasses
do.
This commit is contained in:
Paul Licameli 2015-08-09 23:41:08 -04:00 committed by Paul Licameli
parent 703abe87bc
commit bbfa574790
8 changed files with 499 additions and 359 deletions

View File

@ -1234,6 +1234,7 @@
5E7396591DAFDA3600BA0A4D /* TrackButtonHandles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396571DAFDA3600BA0A4D /* TrackButtonHandles.cpp */; }; 5E7396591DAFDA3600BA0A4D /* TrackButtonHandles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396571DAFDA3600BA0A4D /* TrackButtonHandles.cpp */; };
5E73965C1DAFDAA400BA0A4D /* BackgroundCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965A1DAFDAA400BA0A4D /* BackgroundCell.cpp */; }; 5E73965C1DAFDAA400BA0A4D /* BackgroundCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965A1DAFDAA400BA0A4D /* BackgroundCell.cpp */; };
5E73965F1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */; }; 5E73965F1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */; };
5E7396621DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7396601DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp */; };
5E74D2E31CC4429700D88B0B /* EditCursorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */; }; 5E74D2E31CC4429700D88B0B /* EditCursorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */; };
5E74D2E41CC4429700D88B0B /* PlayIndicatorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DF1CC4429700D88B0B /* PlayIndicatorOverlay.cpp */; }; 5E74D2E41CC4429700D88B0B /* PlayIndicatorOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2DF1CC4429700D88B0B /* PlayIndicatorOverlay.cpp */; };
5E74D2E51CC4429700D88B0B /* Scrubbing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2E11CC4429700D88B0B /* Scrubbing.cpp */; }; 5E74D2E51CC4429700D88B0B /* Scrubbing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E74D2E11CC4429700D88B0B /* Scrubbing.cpp */; };
@ -3073,6 +3074,8 @@
5E73965B1DAFDAA400BA0A4D /* BackgroundCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundCell.h; sourceTree = "<group>"; }; 5E73965B1DAFDAA400BA0A4D /* BackgroundCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundCell.h; sourceTree = "<group>"; };
5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackSelectHandle.cpp; sourceTree = "<group>"; }; 5E73965D1DAFDAEC00BA0A4D /* TrackSelectHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackSelectHandle.cpp; sourceTree = "<group>"; };
5E73965E1DAFDAEC00BA0A4D /* TrackSelectHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackSelectHandle.h; sourceTree = "<group>"; }; 5E73965E1DAFDAEC00BA0A4D /* TrackSelectHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackSelectHandle.h; sourceTree = "<group>"; };
5E7396601DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackPanelResizeHandle.cpp; sourceTree = "<group>"; };
5E7396611DAFDB1E00BA0A4D /* TrackPanelResizeHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelResizeHandle.h; sourceTree = "<group>"; };
5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCell.h; sourceTree = "<group>"; }; 5E74D2D91CC4427B00D88B0B /* TrackPanelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCell.h; sourceTree = "<group>"; };
5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCellIterator.h; sourceTree = "<group>"; }; 5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackPanelCellIterator.h; sourceTree = "<group>"; };
5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditCursorOverlay.cpp; sourceTree = "<group>"; }; 5E74D2DD1CC4429700D88B0B /* EditCursorOverlay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditCursorOverlay.cpp; sourceTree = "<group>"; };
@ -4022,6 +4025,7 @@
1790B0EA09883BFD008A330A /* TrackArtist.cpp */, 1790B0EA09883BFD008A330A /* TrackArtist.cpp */,
1790B0EC09883BFD008A330A /* TrackPanel.cpp */, 1790B0EC09883BFD008A330A /* TrackPanel.cpp */,
1790B0EE09883BFD008A330A /* TrackPanelAx.cpp */, 1790B0EE09883BFD008A330A /* TrackPanelAx.cpp */,
5E7396601DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp */,
5E15123B1DB000C000702E29 /* UIHandle.cpp */, 5E15123B1DB000C000702E29 /* UIHandle.cpp */,
1790B0F209883BFD008A330A /* UndoManager.cpp */, 1790B0F209883BFD008A330A /* UndoManager.cpp */,
5E07842F1DF1E4F400CA76EA /* UserException.cpp */, 5E07842F1DF1E4F400CA76EA /* UserException.cpp */,
@ -4127,6 +4131,7 @@
5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */, 5E74D2DA1CC4427B00D88B0B /* TrackPanelCellIterator.h */,
2803C8B619F35AA000278526 /* TrackPanelListener.h */, 2803C8B619F35AA000278526 /* TrackPanelListener.h */,
5E15123A1DB000C000702E29 /* TrackPanelMouseEvent.h */, 5E15123A1DB000C000702E29 /* TrackPanelMouseEvent.h */,
5E7396611DAFDB1E00BA0A4D /* TrackPanelResizeHandle.h */,
284416391B82D6BC0000574D /* TranslatableStringArray.h */, 284416391B82D6BC0000574D /* TranslatableStringArray.h */,
5E15123C1DB000C000702E29 /* UIHandle.h */, 5E15123C1DB000C000702E29 /* UIHandle.h */,
1790B0F309883BFD008A330A /* UndoManager.h */, 1790B0F309883BFD008A330A /* UndoManager.h */,
@ -7933,6 +7938,7 @@
28F2CED4181867BB00573D61 /* numformatter.cpp in Sources */, 28F2CED4181867BB00573D61 /* numformatter.cpp in Sources */,
28F2CED5181867BB00573D61 /* valnum.cpp in Sources */, 28F2CED5181867BB00573D61 /* valnum.cpp in Sources */,
EDFCEB9C18894AE600C98E51 /* OpenSaveCommands.cpp in Sources */, EDFCEB9C18894AE600C98E51 /* OpenSaveCommands.cpp in Sources */,
5E7396621DAFDB1E00BA0A4D /* TrackPanelResizeHandle.cpp in Sources */,
EDFCEBA618894B2A00C98E51 /* RealFFTf48x.cpp in Sources */, EDFCEBA618894B2A00C98E51 /* RealFFTf48x.cpp in Sources */,
EDFCEBA718894B2A00C98E51 /* SseMathFuncs.cpp in Sources */, EDFCEBA718894B2A00C98E51 /* SseMathFuncs.cpp in Sources */,
EDFCEBB518894B9E00C98E51 /* Equalization48x.cpp in Sources */, EDFCEBB518894B9E00C98E51 /* Equalization48x.cpp in Sources */,

View File

@ -249,6 +249,8 @@ audacity_SOURCES = \
TrackPanelCellIterator.h \ TrackPanelCellIterator.h \
TrackPanelListener.h \ TrackPanelListener.h \
TrackPanelMouseEvent.h \ TrackPanelMouseEvent.h \
TrackPanelResizeHandle.cpp \
TrackPanelResizeHandle.h \
TranslatableStringArray.h \ TranslatableStringArray.h \
UIHandle.h \ UIHandle.h \
UIHandle.cpp \ UIHandle.cpp \

View File

@ -156,7 +156,7 @@ is time to refresh some aspect of the screen.
#include "TrackPanel.h" #include "TrackPanel.h"
#include "TrackPanelCellIterator.h" #include "TrackPanelCellIterator.h"
#include "TrackPanelMouseEvent.h" #include "TrackPanelMouseEvent.h"
#include "TrackPanelResizeHandle.h"
//#define DEBUG_DRAW_TIMING 1 //#define DEBUG_DRAW_TIMING 1
// #define SPECTRAL_EDITING_ESC_KEY // #define SPECTRAL_EDITING_ESC_KEY
@ -382,7 +382,6 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
#endif #endif
mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW); mArrowCursor = std::make_unique<wxCursor>(wxCURSOR_ARROW);
mResizeCursor = std::make_unique<wxCursor>(wxCURSOR_SIZENS);
mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT); mAdjustLeftSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_LEFT);
mAdjustRightSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_RIGHT); mAdjustRightSelectionCursor = std::make_unique<wxCursor>(wxCURSOR_POINT_RIGHT);
@ -861,9 +860,6 @@ void TrackPanel::HandleInterruptedDrag()
case IsUncaptured: case IsUncaptured:
case IsSelecting: case IsSelecting:
case IsSelectingLabelText: case IsSelectingLabelText:
case IsResizing:
case IsResizingBetweenLinkedTracks:
case IsResizingBelowLinkedTracks:
sendEvent = false; sendEvent = false;
default: default:
@ -1006,38 +1002,6 @@ bool TrackPanel::HandleEscapeKey(bool down)
pMixerBoard->Refresh(); pMixerBoard->Refresh();
} }
break; break;
case IsResizing:
mCapturedTrack->SetHeight(mInitialActualHeight);
mCapturedTrack->SetMinimized(mInitialMinimized);
break;
case IsResizingBetweenLinkedTracks:
{
Track *const next = mTracks->GetNext(mCapturedTrack);
mCapturedTrack->SetHeight(mInitialUpperActualHeight);
mCapturedTrack->SetMinimized(mInitialMinimized);
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if( !MONO_WAVE_PAN(mCapturedTrack) )
#endif
{
next->SetHeight(mInitialActualHeight);
next->SetMinimized(mInitialMinimized);
}
}
break;
case IsResizingBelowLinkedTracks:
{
Track *const prev = mTracks->GetPrev(mCapturedTrack);
mCapturedTrack->SetHeight(mInitialActualHeight);
mCapturedTrack->SetMinimized(mInitialMinimized);
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if( !MONO_WAVE_PAN(mCapturedTrack) )
#endif
{
prev->SetHeight(mInitialUpperActualHeight);
prev->SetMinimized(mInitialMinimized);
}
}
break;
default: default:
{ {
// Not escaping from a mouse drag // Not escaping from a mouse drag
@ -1139,23 +1103,6 @@ bool TrackPanel::SetCursorByActivity( )
return false; return false;
} }
/// When in the resize area we can adjust size or relative size.
void TrackPanel::SetCursorAndTipWhenInVResizeArea( bool bLinked, wxString &tip )
{
// Check to see whether it is the first channel of a stereo track
if (bLinked) {
// If we are in the label we got here 'by mistake' and we're
// not actually in the resize area at all. (The resize area
// is shorter when it is between stereo tracks).
tip = _("Click and drag to adjust relative size of stereo tracks.");
SetCursor(*mResizeCursor);
} else {
tip = _("Click and drag to resize the track.");
SetCursor(*mResizeCursor);
}
}
/// When in a label track, find out if we've hit anything that /// When in a label track, find out if we've hit anything that
/// would cause a cursor change. /// would cause a cursor change.
void TrackPanel::SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, void TrackPanel::SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT,
@ -1440,15 +1387,22 @@ void TrackPanel::HandleCursor(wxMouseEvent & event)
wxString tip; wxString tip;
// tip may still be NULL at this point, in which case we go on looking.
// Are we within the vertical resize area? // Are we within the vertical resize area?
// (Add margin back to bottom of the rectangle) // (Add margin back to bottom of the rectangle)
if (within(event.m_y, if (within(event.m_y,
(rect.GetBottom() + (kBottomMargin + kTopMargin) / 2), (rect.GetBottom() + (kBottomMargin + kTopMargin) / 2),
TRACK_RESIZE_REGION)) TRACK_RESIZE_REGION))
SetCursorAndTipWhenInVResizeArea( {
track->GetLinked() && foundCell.type != CellType::Label, tip); HitTestPreview preview
(TrackPanelResizeHandle::HitPreview(
// tip may still be NULL at this point, in which case we go on looking. (foundCell.type != CellType::Label) && track->GetLinked()));
tip = preview.message;
wxCursor *const pCursor = preview.cursor;
if (pCursor)
SetCursor(*pCursor);
}
if (pCell && pCursor == NULL && tip == wxString()) { if (pCell && pCursor == NULL && tip == wxString()) {
const auto size = GetSize(); const auto size = GetSize();
@ -3028,275 +2982,6 @@ bool TrackInfo::HideTopItem( const wxRect &rect, const wxRect &subRect,
return subRect.y + subRect.height - allowance >= rect.y + limit; return subRect.y + subRect.height - allowance >= rect.y + limit;
} }
/// ButtonDown means they just clicked and haven't released yet.
/// We use this opportunity to save which track they clicked on,
/// and the initial height of the track, so as they drag we can
/// update the track size.
void TrackPanel::HandleResizeClick( wxMouseEvent & event )
{
// Get here only if the click was near the bottom of the cell rectangle.
// DM: Figure out what track is about to be resized
const auto foundCell = FindCell(event.m_x, event.m_y);
auto track = foundCell.pTrack;
if (foundCell.type == CellType::Label && track && track->GetLinked())
// Click was at the bottom of a stereo track.
track = track->GetLink();
if (!track) {
return;
}
mMouseClickY = event.m_y;
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
// To do: escape key
if(MONO_WAVE_PAN(track)){
//STM: Determine whether we should rescale one or two tracks
if (track->GetVirtualStereo()) {
// mCapturedTrack is the lower track
mInitialTrackHeight = track->GetHeight(true);
mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
SetCapturedTrack(track, IsResizingBelowLinkedTracks);
}
else {
// mCapturedTrack is the upper track
mInitialTrackHeight = track->GetHeight(true);
mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
SetCapturedTrack(track, IsResizingBetweenLinkedTracks);
}
}
else
#endif
{
Track *prev = mTracks->GetPrev(track);
Track *next = mTracks->GetNext(track);
//STM: Determine whether we should rescale one or two tracks
if (prev && prev->GetLink() == track) {
// mCapturedTrack is the lower track
mInitialTrackHeight = track->GetHeight();
mInitialActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = prev->GetHeight();
mInitialUpperActualHeight = prev->GetActualHeight();
SetCapturedTrack(track, IsResizingBelowLinkedTracks);
}
else if (next && track->GetLink() == next) {
// mCapturedTrack is the upper track
mInitialTrackHeight = next->GetHeight();
mInitialActualHeight = next->GetActualHeight();
mInitialMinimized = next->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
mInitialUpperActualHeight = track->GetActualHeight();
SetCapturedTrack(track, IsResizingBetweenLinkedTracks);
}
else {
// DM: Save the initial mouse location and the initial height
mInitialTrackHeight = track->GetHeight();
mInitialActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
SetCapturedTrack(track, IsResizing);
}
}
}
/// This happens when the button is released from a drag.
/// Since we actually took care of resizing the track when
/// we got drag events, all we have to do here is clean up.
/// We also modify the undo state (the action doesn't become
/// undo-able, but it gets merged with the previous undo-able
/// event).
void TrackPanel::HandleResizeButtonUp(wxMouseEvent & WXUNUSED(event))
{
SetCapturedTrack( NULL );
MakeParentRedrawScrollbars();
MakeParentModifyState(false);
}
/// Resize dragging means that the mouse button IS down and has moved
/// from its initial location. By the time we get here, we
/// have already received a ButtonDown() event and saved the
/// track being resized in mCapturedTrack.
void TrackPanel::HandleResizeDrag(wxMouseEvent & event)
{
int delta = (event.m_y - mMouseClickY);
// On first drag, jump out of minimized mode. Initial height
// will be height of minimized track.
//
// This used to be in HandleResizeClick(), but simply clicking
// on a resize border would switch the minimized state.
if (mCapturedTrack->GetMinimized()) {
Track *link = mCapturedTrack->GetLink();
mCapturedTrack->SetHeight(mCapturedTrack->GetHeight());
mCapturedTrack->SetMinimized(false);
if (link) {
link->SetHeight(link->GetHeight());
link->SetMinimized(false);
// Initial values must be reset since they weren't based on the
// minimized heights.
mInitialUpperTrackHeight = link->GetHeight();
mInitialTrackHeight = mCapturedTrack->GetHeight();
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
else if(MONO_WAVE_PAN(mCapturedTrack)){
mCapturedTrack->SetMinimized(false);
mInitialUpperTrackHeight = mCapturedTrack->GetHeight();
mInitialTrackHeight = mCapturedTrack->GetHeight(true);
}
#endif
}
// Common pieces of code for MONO_WAVE_PAN and otherwise.
auto doResizeBelow = [&] (Track *prev, bool vStereo) {
double proportion = static_cast < double >(mInitialTrackHeight)
/ (mInitialTrackHeight + mInitialUpperTrackHeight);
int newTrackHeight = static_cast < int >
(mInitialTrackHeight + delta * proportion);
int newUpperTrackHeight = static_cast < int >
(mInitialUpperTrackHeight + delta * (1.0 - proportion));
//make sure neither track is smaller than its minimum height
if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
newTrackHeight = mCapturedTrack->GetMinimizedHeight();
if (newUpperTrackHeight < prev->GetMinimizedHeight())
newUpperTrackHeight = prev->GetMinimizedHeight();
mCapturedTrack->SetHeight(newTrackHeight
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
, vStereo
#endif
);
prev->SetHeight(newUpperTrackHeight);
};
auto doResizeBetween = [&] (Track *next, bool vStereo) {
int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
int newTrackHeight = mInitialTrackHeight - delta;
// make sure neither track is smaller than its minimum height
if (newTrackHeight < next->GetMinimizedHeight()) {
newTrackHeight = next->GetMinimizedHeight();
newUpperTrackHeight =
mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
}
if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
newTrackHeight =
mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if (vStereo) {
float temp = 1.0f;
if(newUpperTrackHeight != 0.0f)
temp = (float)newUpperTrackHeight/(float)(newUpperTrackHeight + newTrackHeight);
mCapturedTrack->SetVirtualTrackPercentage(temp);
}
#endif
mCapturedTrack->SetHeight(newUpperTrackHeight);
next->SetHeight(newTrackHeight
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
, vStereo
#endif
);
};
auto doResize = [&] {
int newTrackHeight = mInitialTrackHeight + delta;
if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
newTrackHeight = mCapturedTrack->GetMinimizedHeight();
mCapturedTrack->SetHeight(newTrackHeight);
};
//STM: We may be dragging one or two (stereo) tracks.
// If two, resize proportionally if we are dragging the lower track, and
// adjust compensatively if we are dragging the upper track.
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if(MONO_WAVE_PAN(mCapturedTrack)) {
switch( mMouseCapture )
{
case IsResizingBelowLinkedTracks:
{
doResizeBelow( mCapturedTrack, true );
break;
}
case IsResizingBetweenLinkedTracks:
{
doResizeBetween( mCapturedTrack, true );
break;
}
case IsResizing:
{
// Should imply !MONO_WAVE_PAN(mCapturedTrack),
// so impossible, but anyway:
doResize();
break;
}
default:
// don't refresh in this case.
return;
}
}
else
#endif
{
switch( mMouseCapture )
{
case IsResizingBelowLinkedTracks:
{
Track *prev = mTracks->GetPrev(mCapturedTrack);
doResizeBelow(prev, false);
break;
}
case IsResizingBetweenLinkedTracks:
{
Track *next = mTracks->GetNext(mCapturedTrack);
doResizeBetween(next, false);
break;
}
case IsResizing:
{
doResize();
break;
}
default:
// don't refresh in this case.
return;
}
}
Refresh(false);
}
/// HandleResize gets called when:
/// - A mouse-down event occurs in the "resize region" of a track,
/// i.e. to change its vertical height.
/// - A mouse event occurs and mIsResizing==true (i.e. while
/// the resize is going on)
void TrackPanel::HandleResize(wxMouseEvent & event)
{
if (event.LeftDown()) {
HandleResizeClick( event );
}
else if (event.LeftUp())
{
HandleResizeButtonUp( event );
}
else if (event.Dragging()) {
HandleResizeDrag( event );
}
}
/// Handle mouse wheel rotation (for zoom in/out, vertical and horizontal scrolling) /// Handle mouse wheel rotation (for zoom in/out, vertical and horizontal scrolling)
void TrackPanel::HandleWheelRotation(wxMouseEvent & event) void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
{ {
@ -3657,12 +3342,6 @@ try
} }
} }
else switch( mMouseCapture ) { else switch( mMouseCapture ) {
case IsResizing:
case IsResizingBetweenLinkedTracks:
case IsResizingBelowLinkedTracks:
HandleResize(event);
HandleCursor(event);
break;
case IsAdjustingLabel: case IsAdjustingLabel:
// Reach this case only when the captured track was label // Reach this case only when the captured track was label
HandleGlyphDragRelease(static_cast<LabelTrack *>(mCapturedTrack), event); HandleGlyphDragRelease(static_cast<LabelTrack *>(mCapturedTrack), event);
@ -3885,16 +3564,17 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
auto &pCell = foundCell.pCell; auto &pCell = foundCell.pCell;
auto &rect = foundCell.rect; auto &rect = foundCell.rect;
//call HandleResize if I'm over the border area // see if I'm over the border area.
// (Add margin back to bottom of the rectangle) // TrackPanelResizeHandle is the UIHandle subclass that TrackPanel knows
if (event.LeftDown() && // and uses directly, because allocating area to cells is TrackPanel's business,
pTrack && // and we implement a "hit test" directly here.
if (mUIHandle == NULL &&
event.LeftDown()) {
if (pCell &&
(within(event.m_y, (within(event.m_y,
(rect.GetBottom() + (kBottomMargin + kTopMargin) / 2), (rect.GetBottom() + (kBottomMargin + kTopMargin) / 2),
TRACK_RESIZE_REGION))) { TRACK_RESIZE_REGION)))
HandleResize(event); mUIHandle = &TrackPanelResizeHandle::Instance();
HandleCursor(event);
return;
} }
//Determine if user clicked on the track's left-hand label or ruler //Determine if user clicked on the track's left-hand label or ruler

View File

@ -429,7 +429,6 @@ protected:
protected: protected:
// AS: Cursor handling // AS: Cursor handling
virtual bool SetCursorByActivity( ); virtual bool SetCursorByActivity( );
virtual void SetCursorAndTipWhenInVResizeArea( bool blinked, wxString &tip );
virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, const wxMouseEvent & event, wxString &tip ); virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, const wxMouseEvent & event, wxString &tip );
virtual void SetCursorAndTipWhenSelectTool virtual void SetCursorAndTipWhenSelectTool
( Track * t, const wxMouseEvent & event, const wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor ); ( Track * t, const wxMouseEvent & event, const wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor );
@ -444,12 +443,6 @@ protected:
// MM: Handle mouse wheel rotation // MM: Handle mouse wheel rotation
virtual void HandleWheelRotation(wxMouseEvent & event); virtual void HandleWheelRotation(wxMouseEvent & event);
// Handle resizing.
virtual void HandleResizeClick(wxMouseEvent & event);
virtual void HandleResizeDrag(wxMouseEvent & event);
virtual void HandleResizeButtonUp(wxMouseEvent & event);
virtual void HandleResize(wxMouseEvent & event);
public: public:
virtual void MakeParentRedrawScrollbars(); virtual void MakeParentRedrawScrollbars();
@ -614,8 +607,6 @@ protected:
wxMouseEvent mLastMouseEvent; wxMouseEvent mLastMouseEvent;
int mMouseClickY;
int mMouseMostRecentX; int mMouseMostRecentX;
int mMouseMostRecentY; int mMouseMostRecentY;
@ -675,11 +666,6 @@ protected:
bool onlyWithinSnapDistance, bool onlyWithinSnapDistance,
double *pPinValue = NULL) const; double *pPinValue = NULL) const;
bool mInitialMinimized;
int mInitialTrackHeight;
int mInitialActualHeight;
int mInitialUpperTrackHeight;
int mInitialUpperActualHeight;
bool mAutoScrolling; bool mAutoScrolling;
public: public:
@ -692,9 +678,6 @@ public:
IsSelecting, IsSelecting,
IsAdjustingLabel, IsAdjustingLabel,
IsSelectingLabelText, IsSelectingLabelText,
IsResizing,
IsResizingBetweenLinkedTracks,
IsResizingBelowLinkedTracks,
IsMuting, IsMuting,
IsSoloing, IsSoloing,
IsMinimizing, IsMinimizing,
@ -708,7 +691,7 @@ protected:
std::unique_ptr<wxCursor> std::unique_ptr<wxCursor>
mArrowCursor, mSelectCursor, mArrowCursor, mSelectCursor,
mResizeCursor, mEnvelopeCursor, // doubles as the center frequency cursor mEnvelopeCursor, // doubles as the center frequency cursor
// for spectral selection // for spectral selection
mDisabledCursor, mAdjustLeftSelectionCursor, mAdjustRightSelectionCursor; mDisabledCursor, mAdjustLeftSelectionCursor, mAdjustRightSelectionCursor;
#ifdef EXPERIMENTAL_SPECTRAL_EDITING #ifdef EXPERIMENTAL_SPECTRAL_EDITING

View File

@ -0,0 +1,393 @@
/**********************************************************************
Audacity: A Digital Audio Editor
TrackPanelResizeHandle.cpp
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#include "Audacity.h"
#include "TrackPanelResizeHandle.h"
#include "Experimental.h"
#include "MemoryX.h"
#include <wx/cursor.h>
#include <wx/translation.h>
#include "HitTestResult.h"
#include "Project.h"
#include "RefreshCode.h"
#include "Track.h"
#include "TrackPanelMouseEvent.h"
#include "tracks/ui/TrackControls.h"
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
#include "WaveTrack.h"
#endif
TrackPanelResizeHandle::TrackPanelResizeHandle()
{
}
TrackPanelResizeHandle &TrackPanelResizeHandle::Instance()
{
static TrackPanelResizeHandle instance;
return instance;
}
HitTestPreview TrackPanelResizeHandle::HitPreview(bool bLinked)
{
static wxCursor resizeCursor{ wxCURSOR_SIZENS };
/// When in the resize area we can adjust size or relative size.
// Check to see whether it is the first channel of a stereo track
if (bLinked) {
// If we are in the label we got here 'by mistake' and we're
// not actually in the resize area at all. (The resize area
// is shorter when it is between stereo tracks).
return {
_("Click and drag to adjust relative size of stereo tracks."),
&resizeCursor
};
}
else {
return {
_("Click and drag to resize the track."),
&resizeCursor
};
}
}
TrackPanelResizeHandle::~TrackPanelResizeHandle()
{
}
UIHandle::Result TrackPanelResizeHandle::Click
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
const wxMouseEvent &event = evt.event;
CommonTrackPanelCell *const pCell =
static_cast<CommonTrackPanelCell*>(evt.pCell);
Track *track = track = pCell->FindTrack();
if (track && dynamic_cast< TrackControls * >( pCell )) {
// Clicked under a label;
// if stereo, replace left channel with the right:
if (track && track->GetLinked())
track = track->GetLink();
}
if (!track)
return RefreshCode::Cancelled;
mpTrack = track;
/// ButtonDown means they just clicked and haven't released yet.
/// We use this opportunity to save which track they clicked on,
/// and the initial height of the track, so as they drag we can
/// update the track size.
mMouseClickY = event.m_y;
TrackList *const tracks = pProject->GetTracks();
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if (MONO_WAVE_PAN(track)){
//STM: Determine whether we should rescale one or two tracks
if (track->GetVirtualStereo()) {
// mpTrack is the lower track
mInitialTrackHeight = track->GetHeight(true);
mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
mMode = IsResizingBelowLinkedTracks;
}
else {
// mpTrack is the upper track
mInitialTrackHeight = track->GetHeight(true);
mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
mMode = IsResizingBetweenLinkedTracks;
}
}
else
#endif
{
Track *prev = tracks->GetPrev(track);
Track *next = tracks->GetNext(track);
//STM: Determine whether we should rescale one or two tracks
if (prev && prev->GetLink() == track) {
// mpTrack is the lower track
mInitialTrackHeight = track->GetHeight();
mInitialActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mInitialUpperTrackHeight = prev->GetHeight();
mInitialUpperActualHeight = prev->GetActualHeight();
mMode = IsResizingBelowLinkedTracks;
}
else if (next && track->GetLink() == next) {
// mpTrack is the upper track
mInitialTrackHeight = next->GetHeight();
mInitialActualHeight = next->GetActualHeight();
mInitialMinimized = next->GetMinimized();
mInitialUpperTrackHeight = track->GetHeight();
mInitialUpperActualHeight = track->GetActualHeight();
mMode = IsResizingBetweenLinkedTracks;
}
else {
// DM: Save the initial mouse location and the initial height
mInitialTrackHeight = track->GetHeight();
mInitialActualHeight = track->GetActualHeight();
mInitialMinimized = track->GetMinimized();
mMode = IsResizing;
}
}
return RefreshCode::RefreshNone;
}
UIHandle::Result TrackPanelResizeHandle::Drag
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
{
if ( !mpTrack )
return RefreshCode::Cancelled;
const wxMouseEvent &event = evt.event;
TrackList *const tracks = pProject->GetTracks();
int delta = (event.m_y - mMouseClickY);
// On first drag, jump out of minimized mode. Initial height
// will be height of minimized track.
//
// This used to be in HandleResizeClick(), but simply clicking
// on a resize border would switch the minimized state.
if (mpTrack->GetMinimized()) {
Track *link = mpTrack->GetLink();
mpTrack->SetHeight(mpTrack->GetHeight());
mpTrack->SetMinimized(false);
if (link) {
link->SetHeight(link->GetHeight());
link->SetMinimized(false);
// Initial values must be reset since they weren't based on the
// minimized heights.
mInitialUpperTrackHeight = link->GetHeight();
mInitialTrackHeight = mpTrack->GetHeight();
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
else if (MONO_WAVE_PAN(mpTrack)){
mpTrack->SetMinimized(false);
mInitialUpperTrackHeight = mpTrack->GetHeight();
mInitialTrackHeight = mpTrack->GetHeight(true);
}
#endif
}
// Common pieces of code for MONO_WAVE_PAN and otherwise.
auto doResizeBelow = [&] (Track *prev, bool vStereo) {
double proportion = static_cast < double >(mInitialTrackHeight)
/ (mInitialTrackHeight + mInitialUpperTrackHeight);
int newTrackHeight = static_cast < int >
(mInitialTrackHeight + delta * proportion);
int newUpperTrackHeight = static_cast < int >
(mInitialUpperTrackHeight + delta * (1.0 - proportion));
//make sure neither track is smaller than its minimum height
if (newTrackHeight < mpTrack->GetMinimizedHeight())
newTrackHeight = mpTrack->GetMinimizedHeight();
if (newUpperTrackHeight < prev->GetMinimizedHeight())
newUpperTrackHeight = prev->GetMinimizedHeight();
mpTrack->SetHeight(newTrackHeight
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
, vStereo
#endif
);
prev->SetHeight(newUpperTrackHeight);
};
auto doResizeBetween = [&] (Track *next, bool vStereo) {
int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
int newTrackHeight = mInitialTrackHeight - delta;
// make sure neither track is smaller than its minimum height
if (newTrackHeight < next->GetMinimizedHeight()) {
newTrackHeight = next->GetMinimizedHeight();
newUpperTrackHeight =
mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
}
if (newUpperTrackHeight < mpTrack->GetMinimizedHeight()) {
newUpperTrackHeight = mpTrack->GetMinimizedHeight();
newTrackHeight =
mInitialUpperTrackHeight + mInitialTrackHeight - mpTrack->GetMinimizedHeight();
}
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if (vStereo) {
float temp = 1.0f;
if(newUpperTrackHeight != 0.0f)
temp = (float)newUpperTrackHeight/(float)(newUpperTrackHeight + newTrackHeight);
mpTrack->SetVirtualTrackPercentage(temp);
}
#endif
mpTrack->SetHeight(newUpperTrackHeight);
next->SetHeight(newTrackHeight
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
, vStereo
#endif
);
};
auto doResize = [&] {
int newTrackHeight = mInitialTrackHeight + delta;
if (newTrackHeight < mpTrack->GetMinimizedHeight())
newTrackHeight = mpTrack->GetMinimizedHeight();
mpTrack->SetHeight(newTrackHeight);
};
//STM: We may be dragging one or two (stereo) tracks.
// If two, resize proportionally if we are dragging the lower track, and
// adjust compensatively if we are dragging the upper track.
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if(MONO_WAVE_PAN(mpTrack)) {
switch( mMode )
{
case IsResizingBelowLinkedTracks:
{
doResizeBelow( mpTrack, true );
break;
}
case IsResizingBetweenLinkedTracks:
{
doResizeBetween( mpTrack, true );
break;
}
case IsResizing:
{
// Should imply !MONO_WAVE_PAN(mCapturedTrack),
// so impossible, but anyway:
doResize();
break;
}
default:
// don't refresh in this case.
return RefreshCode::RefreshNone;
}
}
else
#endif
{
switch( mMode )
{
case IsResizingBelowLinkedTracks:
{
Track *prev = tracks->GetPrev(mpTrack);
doResizeBelow(prev, false);
break;
}
case IsResizingBetweenLinkedTracks:
{
Track *next = tracks->GetNext(mpTrack);
doResizeBetween(next, false);
break;
}
case IsResizing:
{
doResize();
break;
}
default:
// don't refresh in this case.
return RefreshCode::RefreshNone;
}
}
return RefreshCode::RefreshAll;
}
HitTestPreview TrackPanelResizeHandle::Preview
(const TrackPanelMouseEvent &, const AudacityProject *)
{
return HitPreview(mMode == IsResizingBetweenLinkedTracks);
}
UIHandle::Result TrackPanelResizeHandle::Release
(const TrackPanelMouseEvent &, AudacityProject *pProject,
wxWindow *)
{
/// This happens when the button is released from a drag.
/// Since we actually took care of resizing the track when
/// we got drag events, all we have to do here is clean up.
/// We also modify the undo state (the action doesn't become
/// undo-able, but it gets merged with the previous undo-able
/// event).
pProject->ModifyState(false);
return RefreshCode::FixScrollbars;
}
UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject)
{
if ( !mpTrack )
return RefreshCode::Cancelled;
TrackList *const tracks = pProject->GetTracks();
switch (mMode) {
case IsResizing:
{
mpTrack->SetHeight(mInitialActualHeight);
mpTrack->SetMinimized(mInitialMinimized);
}
break;
case IsResizingBetweenLinkedTracks:
{
Track *const next = tracks->GetNext(mpTrack);
mpTrack->SetHeight(mInitialUpperActualHeight);
mpTrack->SetMinimized(mInitialMinimized);
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if( !MONO_WAVE_PAN(mpTrack) )
#endif
{
next->SetHeight(mInitialActualHeight);
next->SetMinimized(mInitialMinimized);
}
}
break;
case IsResizingBelowLinkedTracks:
{
Track *const prev = tracks->GetPrev(mpTrack);
mpTrack->SetHeight(mInitialActualHeight);
mpTrack->SetMinimized(mInitialMinimized);
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
if( !MONO_WAVE_PAN(mpTrack) )
#endif
{
prev->SetHeight(mInitialUpperActualHeight);
prev->SetMinimized(mInitialMinimized);
}
}
break;
}
return RefreshCode::RefreshAll;
}
void TrackPanelResizeHandle::OnProjectChange(AudacityProject *pProject)
{
if (! ::GetActiveProject()->GetTracks()->Contains(mpTrack)) {
mpTrack = nullptr;
}
UIHandle::OnProjectChange(pProject);
}

View File

@ -0,0 +1,68 @@
/**********************************************************************
Audacity: A Digital Audio Editor
TrackPanelResizeHandle.h
Paul Licameli split from TrackPanel.cpp
**********************************************************************/
#ifndef __AUDACITY_TRACK_PANEL_RESIZE_HANDLE__
#define __AUDACITY_TRACK_PANEL_RESIZE_HANDLE__
#include "UIHandle.h"
struct HitTestResult;
class Track;
class TrackPanelResizeHandle final : public UIHandle
{
TrackPanelResizeHandle();
TrackPanelResizeHandle(const TrackPanelResizeHandle&) = delete;
TrackPanelResizeHandle &operator=(const TrackPanelResizeHandle&) = delete;
public:
static TrackPanelResizeHandle& Instance();
static HitTestPreview HitPreview(bool bLinked);
virtual ~TrackPanelResizeHandle();
Result Click
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
Result Drag
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
HitTestPreview Preview
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
override;
Result Release
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
wxWindow *pParent) override;
Result Cancel(AudacityProject *pProject) override;
void OnProjectChange(AudacityProject *pProject) override;
private:
enum Mode {
IsResizing,
IsResizingBetweenLinkedTracks,
IsResizingBelowLinkedTracks,
};
Mode mMode{ IsResizing };
Track *mpTrack{};
bool mInitialMinimized{};
int mInitialTrackHeight{};
int mInitialActualHeight{};
int mInitialUpperTrackHeight{};
int mInitialUpperActualHeight{};
int mMouseClickY{};
};
#endif

View File

@ -224,6 +224,7 @@
<ClCompile Include="..\..\..\src\TrackArtist.cpp" /> <ClCompile Include="..\..\..\src\TrackArtist.cpp" />
<ClCompile Include="..\..\..\src\TrackPanel.cpp" /> <ClCompile Include="..\..\..\src\TrackPanel.cpp" />
<ClCompile Include="..\..\..\src\TrackPanelAx.cpp" /> <ClCompile Include="..\..\..\src\TrackPanelAx.cpp" />
<ClCompile Include="..\..\..\src\TrackPanelResizeHandle.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.cpp" /> <ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackUI.cpp" /> <ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackUI.cpp" />
<ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackVRulerControls.cpp" /> <ClCompile Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackVRulerControls.cpp" />
@ -507,6 +508,7 @@
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.h" /> <ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackControls.h" />
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackSliderHandles.h" /> <ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackSliderHandles.h" />
<ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.h" /> <ClInclude Include="..\..\..\src\tracks\playabletrack\wavetrack\ui\WaveTrackVRulerControls.h" />
<ClInclude Include="..\..\..\src\TrackPanelResizeHandle.h" />
<ClInclude Include="..\..\..\src\tracks\ui\BackgroundCell.h" /> <ClInclude Include="..\..\..\src\tracks\ui\BackgroundCell.h" />
<ClInclude Include="..\..\..\src\tracks\ui\CommonTrackPanelCell.h" /> <ClInclude Include="..\..\..\src\tracks\ui\CommonTrackPanelCell.h" />
<ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.h" /> <ClInclude Include="..\..\..\src\tracks\labeltrack\ui\LabelTrackControls.h" />

View File

@ -1028,6 +1028,9 @@
<ClCompile Include="..\..\..\src\tracks\ui\TrackSelectHandle.cpp"> <ClCompile Include="..\..\..\src\tracks\ui\TrackSelectHandle.cpp">
<Filter>src\tracks\ui</Filter> <Filter>src\tracks\ui</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\TrackPanelResizeHandle.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\AboutDialog.h"> <ClInclude Include="..\..\..\src\AboutDialog.h">
@ -2047,6 +2050,9 @@
<ClInclude Include="..\..\..\src\tracks\ui\TrackSelectHandle.h"> <ClInclude Include="..\..\..\src\tracks\ui\TrackSelectHandle.h">
<Filter>src\tracks\ui</Filter> <Filter>src\tracks\ui</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\TrackPanelResizeHandle.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="..\..\audacity.ico"> <Image Include="..\..\audacity.ico">