Audacity  2.2.2
Classes | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
SelectHandle Class Reference

#include <SelectHandle.h>

Inheritance diagram for SelectHandle:
UIHandle

Classes

class  TimerHandler
 

Public Member Functions

 SelectHandle (const std::shared_ptr< Track > &pTrack, bool useSnap, const TrackList &trackList, const TrackPanelMouseState &st, const ViewInfo &viewInfo)
 
SelectHandleoperator= (const SelectHandle &)=default
 
virtual ~SelectHandle ()
 
bool IsClicked () const
 
void SetUseSnap (bool use)
 
void Enter (bool forward) override
 
bool HasSnap () const
 
bool HasEscape () const override
 
bool Escape () override
 
Result Click (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
Result Drag (const TrackPanelMouseEvent &event, AudacityProject *pProject) override
 
HitTestPreview Preview (const TrackPanelMouseState &state, const AudacityProject *pProject) override
 
Result Release (const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
 
Result Cancel (AudacityProject *) override
 
void DrawExtras (DrawingPass pass, wxDC *dc, const wxRegion &updateRegion, const wxRect &panelRect) override
 
- Public Member Functions inherited from UIHandle
virtual ~UIHandle ()=0
 
virtual bool HasRotation () const
 
virtual bool Rotate (bool forward)
 
virtual bool StopsOnKeystroke ()
 
virtual void OnProjectChange (AudacityProject *pProject)
 
Result GetChangeHighlight () const
 
void SetChangeHighlight (Result val)
 

Static Public Member Functions

static UIHandlePtr HitTest (std::weak_ptr< SelectHandle > &holder, const TrackPanelMouseState &state, const AudacityProject *pProject, const std::shared_ptr< Track > &pTrack)
 
static UIHandle::Result NeedChangeHighlight (const SelectHandle &oldState, const SelectHandle &newState)
 
static void SnapCenterOnce (SpectrumAnalyst &analyst, ViewInfo &viewInfo, const WaveTrack *pTrack, bool up)
 
- Static Public Member Functions inherited from UIHandle
static UIHandle::Result NeedChangeHighlight (const UIHandle &, const UIHandle &)
 

Private Types

enum  eFreqSelMode {
  FREQ_SEL_INVALID, FREQ_SEL_SNAPPING_CENTER, FREQ_SEL_PINNED_CENTER, FREQ_SEL_DRAG_CENTER,
  FREQ_SEL_FREE, FREQ_SEL_TOP_FREE, FREQ_SEL_BOTTOM_FREE
}
 

Private Member Functions

 SelectHandle (const SelectHandle &)
 
void Connect (AudacityProject *pProject)
 
void StartSelection (AudacityProject *pProject)
 Reset our selection markers. More...
 
void AdjustSelection (AudacityProject *pProject, ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *pTrack)
 Extend or contract the existing selection. More...
 
void AssignSelection (ViewInfo &viewInfo, double selend, Track *pTrack)
 
void StartFreqSelection (ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, Track *pTrack)
 
void AdjustFreqSelection (const WaveTrack *wt, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight)
 
void HandleCenterFrequencyClick (const ViewInfo &viewInfo, bool shiftDown, const WaveTrack *pTrack, double value)
 
void MoveSnappingFreqSelection (AudacityProject *pProject, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, Track *pTrack)
 

Static Private Member Functions

static void StartSnappingFreqSelection (SpectrumAnalyst &analyst, const ViewInfo &viewInfo, const WaveTrack *pTrack)
 

Private Attributes

std::weak_ptr< TrackmpTrack
 
wxRect mRect {}
 
SelectedRegion mInitialSelection {}
 
std::shared_ptr< SnapManagermSnapManager
 
SnapResults mSnapStart
 
SnapResults mSnapEnd
 
bool mUseSnap { true }
 
bool mSelStartValid {}
 
double mSelStart { 0.0 }
 
int mSelectionBoundary { 0 }
 
enum SelectHandle::eFreqSelMode FREQ_SEL_INVALID
 
std::weak_ptr< const WaveTrackmFreqSelTrack
 
double mFreqSelPin { -1.0 }
 
std::shared_ptr< SpectrumAnalystmFrequencySnapper
 
int mMostRecentX { -1 }
 
int mMostRecentY { -1 }
 
bool mAutoScrolling {}
 
std::shared_ptr
< SelectionStateChanger
mSelectionStateChanger
 
friend TimerHandler
 
std::shared_ptr< TimerHandlermTimerHandler
 

Additional Inherited Members

- Public Types inherited from UIHandle
enum  DrawingPass { Cells, Panel }
 
using Result = unsigned
 
using Cell = TrackPanelCell
 
- Protected Attributes inherited from UIHandle
Result mChangeHighlight { 0 }
 

Detailed Description

Definition at line 32 of file SelectHandle.h.

Member Enumeration Documentation

Enumerator
FREQ_SEL_INVALID 
FREQ_SEL_SNAPPING_CENTER 
FREQ_SEL_PINNED_CENTER 
FREQ_SEL_DRAG_CENTER 
FREQ_SEL_FREE 
FREQ_SEL_TOP_FREE 
FREQ_SEL_BOTTOM_FREE 

Definition at line 139 of file SelectHandle.h.

Constructor & Destructor Documentation

SelectHandle::SelectHandle ( const SelectHandle )
private
SelectHandle::SelectHandle ( const std::shared_ptr< Track > &  pTrack,
bool  useSnap,
const TrackList trackList,
const TrackPanelMouseState st,
const ViewInfo viewInfo 
)
explicit

Definition at line 441 of file SelectHandle.cpp.

444  : mpTrack{ pTrack }
445  , mSnapManager{ std::make_shared<SnapManager>(&trackList, &viewInfo) }
446 {
447  const wxMouseState &state = st.state;
448  mRect = st.rect;
449 
450  auto time = std::max(0.0, viewInfo.PositionToTime(state.m_x, mRect.x));
451  mSnapStart = mSnapManager->Snap(pTrack.get(), time, false);
452  if (mSnapStart.snappedPoint)
453  mSnapStart.outCoord += mRect.x;
454  else
455  mSnapStart.outCoord = -1;
456 
457  mUseSnap = useSnap;
458 }
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ViewInfo.cpp:49
std::shared_ptr< SnapManager > mSnapManager
Definition: SelectHandle.h:130
SnapResults mSnapStart
Definition: SelectHandle.h:131
std::weak_ptr< Track > mpTrack
Definition: SelectHandle.h:126
SelectHandle::~SelectHandle ( )
virtual

Definition at line 460 of file SelectHandle.cpp.

461 {
462 }

Member Function Documentation

void SelectHandle::AdjustFreqSelection ( const WaveTrack wt,
ViewInfo viewInfo,
int  mouseYCoordinate,
int  trackTopEdge,
int  trackHeight 
)
private

Definition at line 1226 of file SelectHandle.cpp.

References FREQ_SEL_BOTTOM_FREE, FREQ_SEL_DRAG_CENTER, FREQ_SEL_INVALID, FREQ_SEL_PINNED_CENTER, FREQ_SEL_SNAPPING_CENTER, FREQ_SEL_TOP_FREE, WaveTrack::GetRate(), mFreqSelPin, min(), ViewInfo::selectedRegion, SelectedRegion::setF0(), SelectedRegion::setF1(), SelectedRegion::setFrequencies(), and SelectedRegion::UndefinedFrequency.

1230 {
1231  if (mFreqSelMode == FREQ_SEL_INVALID ||
1232  mFreqSelMode == FREQ_SEL_SNAPPING_CENTER)
1233  return;
1234 
1235  // Extension happens only when dragging in the same track in which we
1236  // started, and that is of a spectrogram display type.
1237 
1238  const double rate = wt->GetRate();
1239  const double frequency =
1240  PositionToFrequency(wt, true, mouseYCoordinate,
1241  trackTopEdge, trackHeight);
1242 
1243  // Dragging center?
1244  if (mFreqSelMode == FREQ_SEL_DRAG_CENTER) {
1245  if (frequency == rate || frequency < 1.0)
1246  // snapped to top or bottom
1247  viewInfo.selectedRegion.setFrequencies(
1250  else {
1251  // mFreqSelPin holds the ratio of top to center
1252  const double maxRatio = findMaxRatio(frequency, rate);
1253  const double ratio = std::min(maxRatio, mFreqSelPin);
1254  viewInfo.selectedRegion.setFrequencies(
1255  frequency / ratio, frequency * ratio);
1256  }
1257  }
1258  else if (mFreqSelMode == FREQ_SEL_PINNED_CENTER) {
1259  if (mFreqSelPin >= 0) {
1260  // Change both upper and lower edges leaving centre where it is.
1261  if (frequency == rate || frequency < 1.0)
1262  // snapped to top or bottom
1263  viewInfo.selectedRegion.setFrequencies(
1266  else {
1267  // Given center and mouse position, find ratio of the larger to the
1268  // smaller, limit that to the frequency scale bounds, and adjust
1269  // top and bottom accordingly.
1270  const double maxRatio = findMaxRatio(mFreqSelPin, rate);
1271  double ratio = frequency / mFreqSelPin;
1272  if (ratio < 1.0)
1273  ratio = 1.0 / ratio;
1274  ratio = std::min(maxRatio, ratio);
1275  viewInfo.selectedRegion.setFrequencies(
1276  mFreqSelPin / ratio, mFreqSelPin * ratio);
1277  }
1278  }
1279  }
1280  else {
1281  // Dragging of upper or lower.
1282  const bool bottomDefined =
1283  !(mFreqSelMode == FREQ_SEL_TOP_FREE && mFreqSelPin < 0);
1284  const bool topDefined =
1285  !(mFreqSelMode == FREQ_SEL_BOTTOM_FREE && mFreqSelPin < 0);
1286  if (!bottomDefined || (topDefined && mFreqSelPin < frequency)) {
1287  // Adjust top
1288  if (frequency == rate)
1289  // snapped high; upper frequency is undefined
1291  else
1292  viewInfo.selectedRegion.setF1(std::max(1.0, frequency));
1293 
1294  viewInfo.selectedRegion.setF0(mFreqSelPin);
1295  }
1296  else {
1297  // Adjust bottom
1298  if (frequency < 1.0)
1299  // snapped low; lower frequency is undefined
1301  else
1302  viewInfo.selectedRegion.setF0(std::min(rate / 2.0, frequency));
1303 
1304  viewInfo.selectedRegion.setF1(mFreqSelPin);
1305  }
1306  }
1307 }
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
double mFreqSelPin
Definition: SelectHandle.h:157
int min(int a, int b)
bool setF1(double f, bool maySwap=true)
enum SelectHandle::eFreqSelMode FREQ_SEL_INVALID
bool setFrequencies(double f0, double f1)
double GetRate() const
Definition: WaveTrack.cpp:398
static const int UndefinedFrequency
bool setF0(double f, bool maySwap=true)
void SelectHandle::AdjustSelection ( AudacityProject pProject,
ViewInfo viewInfo,
int  mouseXCoordinate,
int  trackLeftEdge,
Track pTrack 
)
private

Extend or contract the existing selection.

Definition at line 1144 of file SelectHandle.cpp.

References AssignSelection(), AudacityProject::GetTracks(), TrackList::Lock(), mpTrack, mSelStart, mSelStartValid, mSnapEnd, mSnapManager, mUseSnap, SnapResults::outCoord, SnapResults::outTime, Track::Pointer(), ZoomInfo::PositionToTime(), SnapResults::Snapped(), SnapResults::snappedPoint, and SnapResults::snappedTime.

1147 {
1148  if (!mSelStartValid)
1149  // Must be dragging frequency bounds only.
1150  return;
1151 
1152  double selend =
1153  std::max(0.0, viewInfo.PositionToTime(mouseXCoordinate, trackLeftEdge));
1154  double origSelend = selend;
1155 
1156  auto pTrack = Track::Pointer( track );
1157  if (!pTrack)
1158  pTrack = pProject->GetTracks()->Lock(mpTrack);
1159 
1160  if (pTrack && mSnapManager.get()) {
1161  bool rightEdge = (selend > mSelStart);
1162  mSnapEnd = mSnapManager->Snap(pTrack.get(), selend, rightEdge);
1163  if (mSnapEnd.Snapped()) {
1164  if (mUseSnap)
1165  selend = mSnapEnd.outTime;
1166  if (mSnapEnd.snappedPoint)
1167  mSnapEnd.outCoord += trackLeftEdge;
1168  }
1169  if (!mSnapEnd.snappedPoint)
1170  mSnapEnd.outCoord = -1;
1171 
1172  // Check if selection endpoints are too close together to snap (unless
1173  // using snap-to-time -- then we always accept the snap results)
1174  if (mSnapStart.outCoord >= 0 &&
1175  mSnapEnd.outCoord >= 0 &&
1176  std::abs(mSnapStart.outCoord - mSnapEnd.outCoord) < 3) {
1177  if(!mSnapEnd.snappedTime)
1178  selend = origSelend;
1179  mSnapEnd.outCoord = -1;
1180  }
1181  }
1182  AssignSelection(viewInfo, selend, pTrack.get());
1183 }
SnapResults mSnapEnd
Definition: SelectHandle.h:131
bool mSelStartValid
Definition: SelectHandle.h:134
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ViewInfo.cpp:49
std::shared_ptr< SnapManager > mSnapManager
Definition: SelectHandle.h:130
bool Snapped() const
Definition: Snap.h:81
bool snappedPoint
Definition: Snap.h:78
wxInt64 outCoord
Definition: Snap.h:77
void AssignSelection(ViewInfo &viewInfo, double selend, Track *pTrack)
SnapResults mSnapStart
Definition: SelectHandle.h:131
double mSelStart
Definition: SelectHandle.h:135
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:734
std::weak_ptr< Track > mpTrack
Definition: SelectHandle.h:126
bool snappedTime
Definition: Snap.h:79
TrackList * GetTracks()
Definition: Project.h:192
static std::shared_ptr< Subclass > Pointer(Track *t)
Definition: Track.h:137
double outTime
Definition: Snap.h:76
void SelectHandle::AssignSelection ( ViewInfo viewInfo,
double  selend,
Track pTrack 
)
private

Definition at line 1186 of file SelectHandle.cpp.

References ODManager::DemandTrackUpdate(), Track::GetKind(), ODManager::Instance, ODManager::IsInstanceCreated(), mSelStart, ViewInfo::selectedRegion, SelectedRegion::setTimes(), and Track::Wave.

Referenced by AdjustSelection(), and SetUseSnap().

1187 {
1188  double sel0, sel1;
1189  if (mSelStart < selend) {
1190  sel0 = mSelStart;
1191  sel1 = selend;
1192  }
1193  else {
1194  sel1 = mSelStart;
1195  sel0 = selend;
1196  }
1197 
1198  viewInfo.selectedRegion.setTimes(sel0, sel1);
1199 
1200  //On-Demand: check to see if there is an OD thing associated with this track. If so we want to update the focal point for the task.
1201  if (pTrack && (pTrack->GetKind() == Track::Wave) && ODManager::IsInstanceCreated())
1203  (static_cast<WaveTrack*>(pTrack),sel0); //sel0 is sometimes less than mSelStart
1204 }
static bool IsInstanceCreated()
returns whether or not the singleton instance was created yet
Definition: ODManager.cpp:205
static ODManager *(* Instance)()
Definition: ODManager.h:49
void DemandTrackUpdate(WaveTrack *track, double seconds)
changes the tasks associated with this Waveform to process the task from a different point in the tra...
Definition: ODManager.cpp:464
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
virtual int GetKind() const
Definition: Track.h:330
double mSelStart
Definition: SelectHandle.h:135
bool setTimes(double t0, double t1)
UIHandle::Result SelectHandle::Cancel ( AudacityProject pProject)
overridevirtual

Implements UIHandle.

Definition at line 1009 of file SelectHandle.cpp.

References AudacityProject::GetMixerBoard(), AudacityProject::GetViewInfo(), mInitialSelection, mSelectionStateChanger, RefreshCode::RefreshAll, and ViewInfo::selectedRegion.

1010 {
1011  mSelectionStateChanger.reset();
1013 
1014  // Refresh mixer board for change of set of selected tracks
1015  if (MixerBoard* pMixerBoard = pProject->GetMixerBoard())
1016  pMixerBoard->Refresh();
1017 
1018  return RefreshCode::RefreshAll;
1019 }
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
Definition: SelectHandle.h:164
MixerBoard * GetMixerBoard()
Definition: Project.h:516
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
SelectedRegion mInitialSelection
Definition: SelectHandle.h:128
UIHandle::Result SelectHandle::Click ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

This method gets called when we're handling selection and the mouse was just clicked.

Implements UIHandle.

Definition at line 528 of file SelectHandle.cpp.

References ViewInfo::bAdjustSelectionEdges, RefreshCode::Cancelled, ODManager::DemandTrackUpdate(), TrackPanelMouseEvent::event, SelectedRegion::fc(), WaveTrack::GetClipAtX(), WaveClip::GetEndTime(), AudacityProject::GetMixerBoard(), WaveClip::GetOffset(), AudacityProject::GetSelectionState(), AudacityProject::GetTrackPanel(), AudacityProject::GetTracks(), AudacityProject::GetViewInfo(), AudacityProject::HandleListSelection(), ODManager::Instance, AudacityProject::IsAudioActive(), ODManager::IsInstanceCreated(), AudacityProject::IsSyncLocked(), Track::Label, TrackList::Lock(), AudacityProject::ModifyState(), RefreshCode::RefreshAll, ViewInfo::selectedRegion, SelectionState::SelectTrackLength(), SelectedRegion::setTimes(), ZoomInfo::TimeToPosition(), RefreshCode::UpdateSelection, and Track::Wave.

529 {
532 
533  using namespace RefreshCode;
534 
535  wxMouseEvent &event = evt.event;
536  const auto sTrack = pProject->GetTracks()->Lock(mpTrack);
537  const auto pTrack = sTrack.get();
538  ViewInfo &viewInfo = pProject->GetViewInfo();
539 
540  mMostRecentX = event.m_x;
541  mMostRecentY = event.m_y;
542 
543  TrackPanel *const trackPanel = pProject->GetTrackPanel();
544 
545  if( pTrack->GetKind() == Track::Label &&
546  event.LeftDown() &&
547  event.ControlDown() ){
548  // We should reach this, only in default of other hits on glyphs or
549  // text boxes.
550  bool bShift = event.ShiftDown();
551  bool unsafe = pProject->IsAudioActive();
552  pProject->HandleListSelection(pTrack, bShift, true, !unsafe);
553  // Do not start a drag
554  return RefreshAll | Cancelled;
555  }
556 
557  auto &selectionState = pProject->GetSelectionState();
558  if (event.LeftDClick() && !event.ShiftDown()) {
559  TrackList *const trackList = pProject->GetTracks();
560 
561  // Deselect all other tracks and select this one.
562  selectionState.SelectNone( *trackList, pProject->GetMixerBoard() );
563 
564  selectionState.SelectTrack
565  ( *trackList, *pTrack, true, true, pProject->GetMixerBoard() );
566 
567  // Default behavior: select whole track
569  ( *trackList, viewInfo, *pTrack, pProject->IsSyncLocked() );
570 
571  // Special case: if we're over a clip in a WaveTrack,
572  // select just that clip
573  if (pTrack->GetKind() == Track::Wave) {
574  WaveTrack *const wt = static_cast<WaveTrack *>(pTrack);
575  WaveClip *const selectedClip = wt->GetClipAtX(event.m_x);
576  if (selectedClip) {
577  viewInfo.selectedRegion.setTimes(
578  selectedClip->GetOffset(), selectedClip->GetEndTime());
579  }
580  }
581 
582  pProject->ModifyState(false);
583 
584  // Do not start a drag
586  }
587  else if (!event.LeftDown())
588  return Cancelled;
589 
590  mInitialSelection = viewInfo.selectedRegion;
591 
592  TrackList *const trackList = pProject->GetTracks();
593  mSelectionStateChanger = std::make_shared< SelectionStateChanger >
594  ( selectionState, *trackList );
595 
596  mSelectionBoundary = 0;
597 
598  bool bShiftDown = event.ShiftDown();
599  bool bCtrlDown = event.ControlDown();
600 
601  auto pMixerBoard = pProject->GetMixerBoard();
602 
604  auto xx = viewInfo.TimeToPosition(mSelStart, mRect.x);
605 
606  // I. Shift-click adjusts an existing selection
607  if (bShiftDown || bCtrlDown) {
608  if (bShiftDown)
609  selectionState.ChangeSelectionOnShiftClick
610  ( *trackList, *pTrack, pMixerBoard );
611  if( bCtrlDown ){
612  //Commented out bIsSelected toggles, as in Track Control Panel.
613  //bool bIsSelected = pTrack->GetSelected();
614  //Actual bIsSelected will always add.
615  bool bIsSelected = false;
616  // Don't toggle away the last selected track.
617  if( !bIsSelected || trackPanel->GetSelectedTrackCount() > 1 )
618  selectionState.SelectTrack
619  ( *trackList, *pTrack, !bIsSelected, true, pMixerBoard );
620  }
621 
622  double value;
623  // Shift-click, choose closest boundary
624  SelectionBoundary boundary =
625  ChooseBoundary(viewInfo, xx, event.m_y, pTrack, mRect, false, false, &value);
626  mSelectionBoundary = boundary;
627  switch (boundary) {
628  case SBLeft:
629  case SBRight:
630  {
631 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
632  // If drag starts, change time selection only
633  // (also exit frequency snapping)
634  mFreqSelMode = FREQ_SEL_INVALID;
635 #endif
636  mSelStartValid = true;
637  mSelStart = value;
639  AdjustSelection(pProject, viewInfo, event.m_x, mRect.x, pTrack);
640  break;
641  }
642 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
643  case SBBottom:
644  case SBTop:
645  {
646  mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
647  mFreqSelPin = value;
648  mFreqSelMode =
649  (boundary == SBBottom)
651 
652  // Drag frequency only, not time:
653  mSelStartValid = false;
655  static_cast<WaveTrack*>(pTrack),
656  viewInfo, event.m_y, mRect.y, mRect.height);
657  break;
658  }
659  case SBCenter:
660  {
661  const auto wt = static_cast<const WaveTrack*>(pTrack);
662  HandleCenterFrequencyClick(viewInfo, true, wt, value);
663  break;
664  }
665 #endif
666  default:
667  wxASSERT(false);
668  };
669 
670  // For persistence of the selection change:
671  pProject->ModifyState(false);
672 
673  // Get timer events so we can auto-scroll
674  Connect(pProject);
675 
676  // Full refresh since the label area may need to indicate
677  // newly selected tracks.
678  return RefreshAll | UpdateSelection;
679  }
680 
681  // II. Unmodified click starts a NEW selection
682 
683  //Make sure you are within the selected track
684  bool startNewSelection = true;
685  if (pTrack && pTrack->GetSelected()) {
686  // Adjusting selection edges can be turned off in the
687  // preferences now
688  if (viewInfo.bAdjustSelectionEdges) {
689 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
690  if (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER &&
691  isSpectralSelectionTrack(pTrack)) {
692  // This code is no longer reachable, but it had a place in the
693  // spectral selection prototype. It used to be that you could be
694  // in a center-frequency-snapping mode that was not a mouse drag
695  // but responded to mouse movements. Click exited that and dragged
696  // width instead. PRL.
697 
698  // Ignore whether we are inside the time selection.
699  // Exit center-snapping, start dragging the width.
700  mFreqSelMode = FREQ_SEL_PINNED_CENTER;
701  mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
702  mFreqSelPin = viewInfo.selectedRegion.fc();
703  // Do not adjust time boundaries
704  mSelStartValid = false;
706  static_cast<WaveTrack*>(pTrack),
707  viewInfo, event.m_y, mRect.y, mRect.height);
708  // For persistence of the selection change:
709  pProject->ModifyState(false);
710  mSelectionBoundary = SBWidth;
711  return UpdateSelection;
712  }
713  else
714 #endif
715  {
716  // Not shift-down, choose boundary only within snapping
717  double value;
718  SelectionBoundary boundary =
719  ChooseBoundary(viewInfo, xx, event.m_y, pTrack, mRect, true, true, &value);
720  mSelectionBoundary = boundary;
721  switch (boundary) {
722  case SBNone:
723  // startNewSelection remains true
724  break;
725  case SBLeft:
726  case SBRight:
727  startNewSelection = false;
728 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
729  // Disable frequency selection
730  mFreqSelMode = FREQ_SEL_INVALID;
731 #endif
732  mSelStartValid = true;
733  mSelStart = value;
735  break;
736 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
737  case SBBottom:
738  case SBTop:
739  case SBWidth:
740  startNewSelection = false;
741  // Disable time selection
742  mSelStartValid = false;
743  mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
744  mFreqSelPin = value;
745  mFreqSelMode =
746  (boundary == SBWidth) ? FREQ_SEL_PINNED_CENTER :
747  (boundary == SBBottom) ? FREQ_SEL_BOTTOM_FREE :
749  break;
750  case SBCenter:
751  {
752  const auto wt = static_cast<const WaveTrack*>(pTrack);
753  HandleCenterFrequencyClick(viewInfo, false, wt, value);
754  startNewSelection = false;
755  break;
756  }
757 #endif
758  default:
759  wxASSERT(false);
760  }
761  }
762  } // bAdjustSelectionEdges
763  }
764 
765  // III. Common case for starting a NEW selection
766 
767  if (startNewSelection) {
768  // If we didn't move a selection boundary, start a NEW selection
769  selectionState.SelectNone( *trackList, pMixerBoard );
770 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
771  StartFreqSelection (viewInfo, event.m_y, mRect.y, mRect.height, pTrack);
772 #endif
773  StartSelection(pProject);
774  selectionState.SelectTrack
775  ( *trackList, *pTrack, true, true, pMixerBoard );
776  trackPanel->SetFocusedTrack(pTrack);
777  //On-Demand: check to see if there is an OD thing associated with this track.
778  if (pTrack->GetKind() == Track::Wave) {
781  (static_cast<WaveTrack*>(pTrack),mSelStart);
782  }
783 
784  Connect(pProject);
785  return RefreshAll | UpdateSelection;
786  }
787  else {
788  Connect(pProject);
789  return RefreshAll;
790  }
791 }
static bool IsInstanceCreated()
returns whether or not the singleton instance was created yet
Definition: ODManager.cpp:205
void AdjustSelection(AudacityProject *pProject, ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *pTrack)
Extend or contract the existing selection.
A list of TrackListNode items.
Definition: Track.h:619
static ODManager *(* Instance)()
Definition: ODManager.h:49
void DemandTrackUpdate(WaveTrack *track, double seconds)
changes the tasks associated with this Waveform to process the task from a different point in the tra...
Definition: ODManager.cpp:464
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
bool mSelStartValid
Definition: SelectHandle.h:134
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
Definition: SelectHandle.h:164
int mSelectionBoundary
Definition: SelectHandle.h:137
double mFreqSelPin
Definition: SelectHandle.h:157
SelectionBoundary
double GetOffset() const
Definition: WaveClip.h:222
MixerBoard * GetMixerBoard()
Definition: Project.h:516
void Connect(AudacityProject *pProject)
The TrackPanel class coordinates updates and operations on the main part of the screen which contains...
Definition: TrackPanel.h:245
WaveClip * GetClipAtX(int xcoord)
Definition: WaveTrack.cpp:2161
SnapResults mSnapStart
Definition: SelectHandle.h:131
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:176
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
SelectionState & GetSelectionState()
Definition: Project.h:309
double mSelStart
Definition: SelectHandle.h:135
void HandleCenterFrequencyClick(const ViewInfo &viewInfo, bool shiftDown, const WaveTrack *pTrack, double value)
bool IsAudioActive() const
Definition: Project.cpp:1454
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:734
void ModifyState(bool bWantsAutoSave)
Definition: Project.cpp:4747
void StartSelection(AudacityProject *pProject)
Reset our selection markers.
enum SelectHandle::eFreqSelMode FREQ_SEL_INVALID
bool IsSyncLocked()
Definition: Project.cpp:5658
std::weak_ptr< Track > mpTrack
Definition: SelectHandle.h:126
void AdjustFreqSelection(const WaveTrack *wt, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight)
double GetEndTime() const
Definition: WaveClip.cpp:427
TrackPanel * GetTrackPanel()
Definition: Project.h:307
TrackList * GetTracks()
Definition: Project.h:192
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
SelectedRegion mInitialSelection
Definition: SelectHandle.h:128
double outTime
Definition: Snap.h:76
void HandleListSelection(Track *t, bool shift, bool ctrl, bool modifyState)
Definition: Menus.cpp:3578
void StartFreqSelection(ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, Track *pTrack)
static void SelectTrackLength(TrackList &tracks, ViewInfo &viewInfo, Track &track, bool syncLocked)
std::weak_ptr< const WaveTrack > mFreqSelTrack
Definition: SelectHandle.h:150
double timeSnappedTime
Definition: Snap.h:75
void SelectHandle::Connect ( AudacityProject pProject)
private

Definition at line 1034 of file SelectHandle.cpp.

References mTimerHandler.

1035 {
1036  mTimerHandler = std::make_shared<TimerHandler>( this, pProject );
1037 }
std::shared_ptr< TimerHandler > mTimerHandler
Definition: SelectHandle.h:168
UIHandle::Result SelectHandle::Drag ( const TrackPanelMouseEvent event,
AudacityProject pProject 
)
overridevirtual

AS: If we're dragging to adjust a selection (or actually, if the screen is scrolling while you're selecting), we handle it here.

Implements UIHandle.

Definition at line 794 of file SelectHandle.cpp.

References TrackPanelMouseEvent::event, AudacityProject::GetMixerBoard(), AudacityProject::GetSelectionState(), AudacityProject::GetTracks(), AudacityProject::GetViewInfo(), SelectedRegion::isPoint(), TrackList::Lock(), TrackPanelMouseEvent::pCell, RefreshCode::RefreshNone, ViewInfo::selectedRegion, SelectionState::SelectRangeOfTracks(), and ZoomInfo::TimeToPosition().

Referenced by SelectHandle::TimerHandler::OnTimer().

795 {
796  using namespace RefreshCode;
797 
798  ViewInfo &viewInfo = pProject->GetViewInfo();
799  const wxMouseEvent &event = evt.event;
800 
801  int x = mAutoScrolling ? mMostRecentX : event.m_x;
802  int y = mAutoScrolling ? mMostRecentY : event.m_y;
803  mMostRecentX = x;
804  mMostRecentY = y;
805 
809 
810  // Fuhggeddaboudit if we're not dragging and not autoscrolling.
811  if (!event.Dragging() && !mAutoScrolling)
812  return RefreshNone;
813 
814  if (event.CmdDown()) {
815  // Ctrl-drag has no meaning, fuhggeddaboudit
816  // JKC YES it has meaning.
817  //return RefreshNone;
818  }
819 
820  // Also fuhggeddaboudit if not in a track.
821  auto pTrack = pProject->GetTracks()->Lock(mpTrack);
822  if (!pTrack)
823  return RefreshNone;
824 
825  // JKC: Logic to prevent a selection smaller than 5 pixels to
826  // prevent accidental dragging when selecting.
827  // (if user really wants a tiny selection, they should zoom in).
828  // Can someone make this value of '5' configurable in
829  // preferences?
830  enum { minimumSizedSelection = 5 }; //measured in pixels
831 
832  // Might be dragging frequency bounds only, test
833  if (mSelStartValid) {
834  wxInt64 SelStart = viewInfo.TimeToPosition(mSelStart, mRect.x); //cvt time to pixels.
835  // Abandon this drag if selecting < 5 pixels.
836  if (wxLongLong(SelStart - x).Abs() < minimumSizedSelection)
837  return RefreshNone;
838  }
839 
840  if ( auto clickedTrack =
841  static_cast<CommonTrackPanelCell*>(evt.pCell.get())->FindTrack() ) {
842  // Handle which tracks are selected
843  Track *sTrack = pTrack.get();
844  Track *eTrack = clickedTrack.get();
845  auto trackList = pProject->GetTracks();
846  auto pMixerBoard = pProject->GetMixerBoard();
847  if ( sTrack && eTrack && !event.ControlDown() ) {
848  auto &selectionState = pProject->GetSelectionState();
849  selectionState.SelectRangeOfTracks
850  ( *trackList, *sTrack, *eTrack, pMixerBoard );
851  }
852 
853 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
854 #ifndef SPECTRAL_EDITING_ESC_KEY
855  if (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER &&
856  !viewInfo.selectedRegion.isPoint())
858  (pProject, viewInfo, y, mRect.y, mRect.height, pTrack.get());
859  else
860 #endif
861  if (pProject->GetTracks()->Lock(mFreqSelTrack) == pTrack)
863  static_cast<WaveTrack*>(pTrack.get()),
864  viewInfo, y, mRect.y, mRect.height);
865 #endif
866 
867  AdjustSelection(pProject, viewInfo, x, mRect.x, clickedTrack.get());
868  }
869 
870  return RefreshNone
871 
872  // If scrubbing does not use the helper poller thread, then
873  // don't refresh at every mouse event, because it slows down seek-scrub.
874  // Instead, let OnTimer do it, which is often enough.
875  // And even if scrubbing does use the thread, then skipping refresh does not
876  // bring that advantage, but it is probably still a good idea anyway.
877 
878  // | UpdateSelection
879 
880  ;
881 }
void MoveSnappingFreqSelection(AudacityProject *pProject, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight, Track *pTrack)
void AdjustSelection(AudacityProject *pProject, ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge, Track *pTrack)
Extend or contract the existing selection.
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
bool mSelStartValid
Definition: SelectHandle.h:134
MixerBoard * GetMixerBoard()
Definition: Project.h:516
bool mAutoScrolling
Definition: SelectHandle.h:162
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:102
SelectionState & GetSelectionState()
Definition: Project.h:309
double mSelStart
Definition: SelectHandle.h:135
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
Definition: Track.h:734
std::weak_ptr< Track > mpTrack
Definition: SelectHandle.h:126
void AdjustFreqSelection(const WaveTrack *wt, ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge, int trackHeight)
TrackList * GetTracks()
Definition: Project.h:192
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
void SelectRangeOfTracks(TrackList &tracks, Track &sTrack, Track &eTrack, MixerBoard *pMixerBoard)
std::weak_ptr< const WaveTrack > mFreqSelTrack
Definition: SelectHandle.h:150
void SelectHandle::DrawExtras ( DrawingPass  pass,
wxDC *  dc,
const wxRegion &  updateRegion,
const wxRect &  panelRect 
)
overridevirtual

Reimplemented from UIHandle.

Definition at line 1022 of file SelectHandle.cpp.

1023 {
1024  if (pass == Panel) {
1025  // Draw snap guidelines if we have any
1026  if ( mSnapManager ) {
1027  auto coord1 = (mUseSnap || IsClicked()) ? mSnapStart.outCoord : -1;
1028  auto coord2 = (!mUseSnap || !IsClicked()) ? -1 : mSnapEnd.outCoord;
1029  mSnapManager->Draw( dc, coord1, coord2 );
1030  }
1031  }
1032 }
SnapResults mSnapEnd
Definition: SelectHandle.h:131
std::shared_ptr< SnapManager > mSnapManager
Definition: SelectHandle.h:130
wxInt64 outCoord
Definition: Snap.h:77
SnapResults mSnapStart
Definition: SelectHandle.h:131
bool IsClicked() const
void SelectHandle::Enter ( bool  forward)
overridevirtual

Reimplemented from UIHandle.

Definition at line 483 of file SelectHandle.cpp.

References SetUseSnap().

484 {
485  SetUseSnap(true);
486 }
void SetUseSnap(bool use)
bool SelectHandle::Escape ( )
overridevirtual

Reimplemented from UIHandle.

Definition at line 518 of file SelectHandle.cpp.

References HasEscape(), and SetUseSnap().

519 {
520  if (SelectHandle::HasEscape()) {
521  SetUseSnap(false);
522  return true;
523  }
524  return false;
525 }
bool HasEscape() const override
void SetUseSnap(bool use)
void SelectHandle::HandleCenterFrequencyClick ( const ViewInfo viewInfo,
bool  shiftDown,
const WaveTrack pTrack,
double  value 
)
private

Definition at line 1310 of file SelectHandle.cpp.

References FREQ_SEL_DRAG_CENTER, FREQ_SEL_SNAPPING_CENTER, mFreqSelPin, mFreqSelTrack, mFrequencySnapper, mSelStartValid, and StartSnappingFreqSelection().

1311 {
1312  if (shiftDown) {
1313  // Disable time selection
1314  mSelStartValid = false;
1315  mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
1316  mFreqSelPin = value;
1317  mFreqSelMode = FREQ_SEL_DRAG_CENTER;
1318  }
1319  else {
1320 #ifndef SPECTRAL_EDITING_ESC_KEY
1321  // Start center snapping
1322  // Turn center snapping on (the only way to do this)
1323  mFreqSelMode = FREQ_SEL_SNAPPING_CENTER;
1324  // Disable time selection
1325  mSelStartValid = false;
1326  mFrequencySnapper = std::make_shared<SpectrumAnalyst>();
1327  StartSnappingFreqSelection(*mFrequencySnapper, viewInfo, pTrack);
1328 #endif
1329  }
1330 }
std::shared_ptr< SpectrumAnalyst > mFrequencySnapper
Definition: SelectHandle.h:158
bool mSelStartValid
Definition: SelectHandle.h:134
double mFreqSelPin
Definition: SelectHandle.h:157
static void StartSnappingFreqSelection(SpectrumAnalyst &analyst, const ViewInfo &viewInfo, const WaveTrack *pTrack)
std::weak_ptr< const WaveTrack > mFreqSelTrack
Definition: SelectHandle.h:150
bool SelectHandle::HasEscape ( ) const
overridevirtual

Reimplemented from UIHandle.

Definition at line 513 of file SelectHandle.cpp.

References HasSnap(), and mUseSnap.

Referenced by Escape().

514 {
515  return HasSnap() && mUseSnap;
516 }
bool HasSnap() const
bool SelectHandle::HasSnap ( ) const

Definition at line 507 of file SelectHandle.cpp.

References IsClicked(), and mSnapEnd.

Referenced by HasEscape(), and SetUseSnap().

508 {
509  return
510  (IsClicked() ? mSnapEnd : mSnapStart).snappedPoint;
511 }
SnapResults mSnapEnd
Definition: SelectHandle.h:131
SnapResults mSnapStart
Definition: SelectHandle.h:131
bool IsClicked() const
UIHandlePtr SelectHandle::HitTest ( std::weak_ptr< SelectHandle > &  holder,
const TrackPanelMouseState state,
const AudacityProject pProject,
const std::shared_ptr< Track > &  pTrack 
)
static

Definition at line 375 of file SelectHandle.cpp.

References AssignUIHandlePtr(), ViewInfo::bAdjustSelectionEdges, AudacityProject::GetTracks(), AudacityProject::GetViewInfo(), TrackPanelMouseState::rect, ViewInfo::selectedRegion, SelectedRegion::t0(), SelectedRegion::t1(), and ZoomInfo::TimeToPosition().

Referenced by Track::HitTest().

378 {
379  // This handle is a little special because there may be some state to
380  // preserve during movement before the click.
381  auto old = holder.lock();
382  bool oldUseSnap = true;
383  if (old) {
384  // It should not have started listening to timer events
385  if( old->mTimerHandler ) {
386  wxASSERT(false);
387  // Handle this eventuality anyway, don't leave a dangling back-pointer
388  // in the attached event handler.
389  old->mTimerHandler.reset();
390  }
391  oldUseSnap = old->mUseSnap;
392  }
393 
394  const ViewInfo &viewInfo = pProject->GetViewInfo();
395  auto result = std::make_shared<SelectHandle>(
396  pTrack, oldUseSnap, *pProject->GetTracks(), st, viewInfo );
397 
398  result = AssignUIHandlePtr(holder, result);
399 
400  //Make sure we are within the selected track
401  // Adjusting the selection edges can be turned off in
402  // the preferences...
403  if (!pTrack->GetSelected() || !viewInfo.bAdjustSelectionEdges)
404  {
405  return result;
406  }
407 
408  {
409  const wxRect &rect = st.rect;
410  wxInt64 leftSel = viewInfo.TimeToPosition(viewInfo.selectedRegion.t0(), rect.x);
411  wxInt64 rightSel = viewInfo.TimeToPosition(viewInfo.selectedRegion.t1(), rect.x);
412  // Something is wrong if right edge comes before left edge
413  wxASSERT(!(rightSel < leftSel));
414  static_cast<void>(leftSel); // Suppress unused variable warnings if not in debug-mode
415  static_cast<void>(rightSel);
416  }
417 
418  return result;
419 }
double t0() const
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
bool bAdjustSelectionEdges
Definition: ViewInfo.h:185
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
double t1() const
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ViewInfo.cpp:59
TrackList * GetTracks()
Definition: Project.h:192
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:162
bool SelectHandle::IsClicked ( ) const

Definition at line 55 of file SelectHandle.cpp.

References mSelectionStateChanger.

Referenced by HasSnap(), and SetUseSnap().

56 {
57  return mSelectionStateChanger.get() != NULL;
58 }
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
Definition: SelectHandle.h:164
void SelectHandle::MoveSnappingFreqSelection ( AudacityProject pProject,
ViewInfo viewInfo,
int  mouseYCoordinate,
int  trackTopEdge,
int  trackHeight,
Track pTrack 
)
private

Definition at line 1376 of file SelectHandle.cpp.

References SelectedRegion::f0(), SelectedRegion::f1(), WaveTrack::GetRate(), Track::GetSelected(), AudacityProject::GetTrackPanel(), mFreqSelPin, mFreqSelTrack, mFrequencySnapper, min(), ViewInfo::selectedRegion, TrackPanel::SetFocusedTrack(), and SelectedRegion::setFrequencies().

1379 {
1380  if (pTrack &&
1381  pTrack->GetSelected() &&
1382  isSpectralSelectionTrack(pTrack)) {
1383  // Spectral selection track is always wave
1384  WaveTrack *const wt = static_cast<WaveTrack*>(pTrack);
1385  // PRL:
1386  // What would happen if center snapping selection began in one spectrogram track,
1387  // then continues inside another? We do not then recalculate
1388  // the spectrum (as was done in StartSnappingFreqSelection)
1389  // but snap according to the peaks in the old track.
1390 
1391  // But if we always supply the original clicked track here that doesn't matter.
1392  const double rate = wt->GetRate();
1393  const double frequency =
1394  PositionToFrequency(wt, false, mouseYCoordinate,
1395  trackTopEdge, trackHeight);
1396  const double snappedFrequency =
1397  mFrequencySnapper->FindPeak(frequency, NULL);
1398  const double maxRatio = findMaxRatio(snappedFrequency, rate);
1399  double ratio = 2.0; // An arbitrary octave on each side, at most
1400  {
1401  const double f0 = viewInfo.selectedRegion.f0();
1402  const double f1 = viewInfo.selectedRegion.f1();
1403  if (f1 >= f0 && f0 >= 0)
1404  // Preserve already chosen ratio instead
1405  ratio = sqrt(f1 / f0);
1406  }
1407  ratio = std::min(ratio, maxRatio);
1408 
1409  mFreqSelPin = snappedFrequency;
1410  viewInfo.selectedRegion.setFrequencies(
1411  snappedFrequency / ratio, snappedFrequency * ratio);
1412 
1413  // A change here would affect what AdjustFreqSelection() does
1414  // in the prototype version where you switch from moving center to
1415  // dragging width with a click. No effect now.
1416  mFreqSelTrack = Track::Pointer<const WaveTrack>( wt );
1417 
1418  // SelectNone();
1419  // SelectTrack(pTrack, true);
1420  pProject->GetTrackPanel()->SetFocusedTrack(pTrack);
1421  }
1422 }
std::shared_ptr< SpectrumAnalyst > mFrequencySnapper
Definition: SelectHandle.h:158
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
bool GetSelected() const
Definition: Track.h:276
double mFreqSelPin
Definition: SelectHandle.h:157
void SetFocusedTrack(Track *t)
double f0() const
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
int min(int a, int b)
double f1() const
TrackPanel * GetTrackPanel()
Definition: Project.h:307
bool setFrequencies(double f0, double f1)
double GetRate() const
Definition: WaveTrack.cpp:398
std::weak_ptr< const WaveTrack > mFreqSelTrack
Definition: SelectHandle.h:150
UIHandle::Result SelectHandle::NeedChangeHighlight ( const SelectHandle oldState,
const SelectHandle newState 
)
static

Definition at line 422 of file SelectHandle.cpp.

References mSnapStart, mUseSnap, and RefreshCode::RefreshAll.

423 {
424  auto useSnap = oldState.mUseSnap;
425  // This is guaranteed when constructing the NEW handle:
426  wxASSERT( useSnap == newState.mUseSnap );
427  if (!useSnap)
428  return 0;
429 
430  auto &oldSnapState = oldState.mSnapStart;
431  auto &newSnapState = newState.mSnapStart;
432  if ( oldSnapState.Snapped() == newSnapState.Snapped() &&
433  (!oldSnapState.Snapped() ||
434  oldSnapState.outCoord == newSnapState.outCoord) )
435  return 0;
436 
438 }
SnapResults mSnapStart
Definition: SelectHandle.h:131
SelectHandle& SelectHandle::operator= ( const SelectHandle )
default
HitTestPreview SelectHandle::Preview ( const TrackPanelMouseState state,
const AudacityProject pProject 
)
overridevirtual

Implements UIHandle.

Definition at line 884 of file SelectHandle.cpp.

References _(), ViewInfo::bAdjustSelectionEdges, NormalizedKeyString::Display(), AudacityProject::GetCommandManager(), CommandManager::GetKeyFromName(), AudacityProject::GetToolsToolBar(), AudacityProject::GetViewInfo(), ToolsToolBar::IsDown(), multiTool, TrackPanelMouseState::rect, TrackPanelMouseState::state, and ZoomInfo::TimeToPosition().

885 {
886  if (!HasSnap() && !mUseSnap)
887  // Moved out of snapping; revert to un-escaped state
888  mUseSnap = true;
889 
890  auto pTrack = mpTrack.lock();
891  if (!pTrack)
892  return {};
893 
894  wxString tip;
895  wxCursor *pCursor = SelectCursor();
896  if ( IsClicked() )
897  // Use same cursor as at the clck
898  SetTipAndCursorForBoundary
900  (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER),
901  tip, pCursor);
902  else {
903  // Choose one of many cursors for mouse-over
904 
905  const ViewInfo &viewInfo = pProject->GetViewInfo();
906 
907  auto &state = st.state;
909  auto xx = viewInfo.TimeToPosition(time, mRect.x);
910 
911  const bool bMultiToolMode =
912  pProject->GetToolsToolBar()->IsDown(multiTool);
913 
914  //In Multi-tool mode, give multitool prompt if no-special-hit.
915  if (bMultiToolMode) {
916  // Look up the current key binding for Preferences.
917  // (Don't assume it's the default!)
918  auto keyStr =
919  pProject->GetCommandManager()->GetKeyFromName(wxT("Preferences"))
920  .Display( true );
921  if (keyStr.empty())
922  // No keyboard preference defined for opening Preferences dialog
923  /* i18n-hint: These are the names of a menu and a command in that menu */
924  keyStr = _("Edit, Preferences...");
925 
926  /* i18n-hint: %s is usually replaced by "Ctrl+P" for Windows/Linux, "Command+," for Mac */
927  tip = wxString::Format(
928  _("Multi-Tool Mode: %s for Mouse and Keyboard Preferences."),
929  keyStr);
930  // Later in this function we may point to some other string instead.
931  if (!pTrack->GetSelected() ||
932  !viewInfo.bAdjustSelectionEdges)
933  ;
934  else {
935  const wxRect &rect = st.rect;
936  const bool bShiftDown = state.ShiftDown();
937  const bool bCtrlDown = state.ControlDown();
938  const bool bModifierDown = bShiftDown || bCtrlDown;
939 
940  // If not shift-down and not snapping center, then
941  // choose boundaries only in snapping tolerance,
942  // and may choose center.
943  SelectionBoundary boundary =
944  ChooseBoundary(viewInfo, xx, state.m_y, pTrack.get(), rect, !bModifierDown, !bModifierDown);
945 
946  SetTipAndCursorForBoundary(boundary, !bShiftDown, tip, pCursor);
947  }
948  }
949 
950 #if 0
951  // This is a vestige of an idea in the prototype version.
952  // Center would snap without mouse button down, click would pin the center
953  // and drag width.
954 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
955  if ((mFreqSelMode == FREQ_SEL_SNAPPING_CENTER) &&
956  isSpectralSelectionTrack(pTrack)) {
957  // Not shift-down, but center frequency snapping toggle is on
958  tip = _("Click and drag to set frequency bandwidth.");
959  pCursor = &*envelopeCursor;
960  return {};
961  }
962 #endif
963 #endif
964 
965  if (!pTrack->GetSelected() || !viewInfo.bAdjustSelectionEdges)
966  ;
967  else {
968  const wxRect &rect = st.rect;
969  const bool bShiftDown = state.ShiftDown();
970  const bool bCtrlDown = state.ControlDown();
971  const bool bModifierDown = bShiftDown || bCtrlDown;
972  SelectionBoundary boundary = ChooseBoundary(
973  viewInfo, xx, state.m_y, pTrack.get(), rect, !bModifierDown, !bModifierDown);
974  SetTipAndCursorForBoundary(boundary, !bShiftDown, tip, pCursor);
975  }
976 
977  MaySetOnDemandTip(pTrack.get(), tip);
978  }
979  if (tip == "") {
980  tip = _("Click and drag to select audio");
981  }
982  if (HasEscape() && mUseSnap) {
983  tip += wxT(" ") +
984 /* i18n-hint: "Snapping" means automatic alignment of selection edges to any nearby label or clip boundaries */
985  _("(snapping)");
986  }
987  return { tip, pCursor };
988 }
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
bool bAdjustSelectionEdges
Definition: ViewInfo.h:185
bool HasSnap() const
int mSelectionBoundary
Definition: SelectHandle.h:137
SelectionBoundary
CommandManager * GetCommandManager()
Definition: Project.h:346
ToolsToolBar * GetToolsToolBar()
Definition: Project.cpp:5066
SnapResults mSnapStart
Definition: SelectHandle.h:131
bool HasEscape() const override
wxInt64 TimeToPosition(double time, wxInt64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Definition: ViewInfo.cpp:59
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
bool IsDown(int tool) const
bool IsClicked() const
std::weak_ptr< Track > mpTrack
Definition: SelectHandle.h:126
NormalizedKeyString GetKeyFromName(const wxString &name) const
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
wxString Display(bool usesSpecialChars=false) const
Definition: Keyboard.cpp:53
double outTime
Definition: Snap.h:76
double timeSnappedTime
Definition: Snap.h:75
UIHandle::Result SelectHandle::Release ( const TrackPanelMouseEvent event,
AudacityProject pProject,
wxWindow *  pParent 
)
overridevirtual

Implements UIHandle.

Definition at line 991 of file SelectHandle.cpp.

References AudacityProject::ModifyState(), RefreshCode::RefreshAll, and RefreshCode::RefreshNone.

993 {
994  using namespace RefreshCode;
995  pProject->ModifyState(false);
996  mFrequencySnapper.reset();
997  mSnapManager.reset();
999  mSelectionStateChanger->Commit();
1000  mSelectionStateChanger.reset();
1001  }
1002 
1003  if (mUseSnap && (mSnapStart.outCoord != -1 || mSnapEnd.outCoord != -1))
1004  return RefreshAll;
1005  else
1006  return RefreshNone;
1007 }
std::shared_ptr< SpectrumAnalyst > mFrequencySnapper
Definition: SelectHandle.h:158
SnapResults mSnapEnd
Definition: SelectHandle.h:131
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
Definition: SelectHandle.h:164
std::shared_ptr< SnapManager > mSnapManager
Definition: SelectHandle.h:130
wxInt64 outCoord
Definition: Snap.h:77
SnapResults mSnapStart
Definition: SelectHandle.h:131
void ModifyState(bool bWantsAutoSave)
Definition: Project.cpp:4747
void SelectHandle::SetUseSnap ( bool  use)

Definition at line 488 of file SelectHandle.cpp.

References AssignSelection(), GetActiveProject(), HasSnap(), IsClicked(), UIHandle::mChangeHighlight, mSnapEnd, mUseSnap, SnapResults::outTime, RefreshCode::RefreshAll, SnapResults::timeSnappedTime, and RefreshCode::UpdateSelection.

Referenced by Enter(), and Escape().

489 {
490  mUseSnap = use;
491 
492  bool hasSnap = HasSnap();
493  if (hasSnap)
494  // Repaint to turn the snap lines on or off
496 
497  if (IsClicked()) {
498  // Readjust the moving selection end
500  ::GetActiveProject()->GetViewInfo(),
502  nullptr);
504  }
505 }
SnapResults mSnapEnd
Definition: SelectHandle.h:131
bool HasSnap() const
Result mChangeHighlight
Definition: UIHandle.h:150
void AssignSelection(ViewInfo &viewInfo, double selend, Track *pTrack)
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
bool IsClicked() const
double outTime
Definition: Snap.h:76
double timeSnappedTime
Definition: Snap.h:75
void SelectHandle::SnapCenterOnce ( SpectrumAnalyst analyst,
ViewInfo viewInfo,
const WaveTrack pTrack,
bool  up 
)
static

Definition at line 1425 of file SelectHandle.cpp.

References SelectedRegion::f1(), SelectedRegion::fc(), SpectrumAnalyst::FindPeak(), SpectrogramSettings::GetFFTLength(), WaveTrack::GetRate(), WaveTrack::GetSpectrogramSettings(), min(), ViewInfo::selectedRegion, SelectedRegion::setFrequencies(), and StartSnappingFreqSelection().

Referenced by AudacityProject::DoNextPeakFrequency().

1427 {
1428  const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
1429  const auto windowSize = settings.GetFFTLength();
1430  const double rate = pTrack->GetRate();
1431  const double nyq = rate / 2.0;
1432  const double binFrequency = rate / windowSize;
1433 
1434  double f1 = viewInfo.selectedRegion.f1();
1435  double centerFrequency = viewInfo.selectedRegion.fc();
1436  if (centerFrequency <= 0) {
1437  centerFrequency = up ? binFrequency : nyq;
1438  f1 = centerFrequency * sqrt(2.0);
1439  }
1440 
1441  double ratio = f1 / centerFrequency;
1442  const int originalBin = floor(0.5 + centerFrequency / binFrequency);
1443  const int limitingBin = up ? floor(0.5 + nyq / binFrequency) : 1;
1444 
1445  // This is crude and wasteful, doing the FFT each time the command is called.
1446  // It would be better to cache the data, but then invalidation of the cache would
1447  // need doing in all places that change the time selection.
1448  StartSnappingFreqSelection(analyst, viewInfo, pTrack);
1449  double snappedFrequency = centerFrequency;
1450  int bin = originalBin;
1451  if (up) {
1452  while (snappedFrequency <= centerFrequency &&
1453  bin < limitingBin)
1454  snappedFrequency = analyst.FindPeak(++bin * binFrequency, NULL);
1455  }
1456  else {
1457  while (snappedFrequency >= centerFrequency &&
1458  bin > limitingBin)
1459  snappedFrequency = analyst.FindPeak(--bin * binFrequency, NULL);
1460  }
1461 
1462  // PRL: added these two lines with the big TrackPanel refactor
1463  const double maxRatio = findMaxRatio(snappedFrequency, rate);
1464  ratio = std::min(ratio, maxRatio);
1465 
1467  (snappedFrequency / ratio, snappedFrequency * ratio);
1468 }
float FindPeak(float xPos, float *pY) const
Spectrogram settings, either for one track or as defaults.
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
size_t GetFFTLength() const
const SpectrogramSettings & GetSpectrogramSettings() const
Definition: WaveTrack.cpp:690
static void StartSnappingFreqSelection(SpectrumAnalyst &analyst, const ViewInfo &viewInfo, const WaveTrack *pTrack)
int min(int a, int b)
double fc() const
double f1() const
bool setFrequencies(double f0, double f1)
double GetRate() const
Definition: WaveTrack.cpp:398
void SelectHandle::StartFreqSelection ( ViewInfo viewInfo,
int  mouseYCoordinate,
int  trackTopEdge,
int  trackHeight,
Track pTrack 
)
private

Definition at line 1206 of file SelectHandle.cpp.

References FREQ_SEL_FREE, FREQ_SEL_INVALID, mFreqSelPin, mFreqSelTrack, ViewInfo::selectedRegion, SelectedRegion::setFrequencies(), and SelectedRegion::UndefinedFrequency.

1209 {
1210  mFreqSelTrack.reset();
1211  mFreqSelMode = FREQ_SEL_INVALID;
1213 
1214  if (isSpectralSelectionTrack(pTrack)) {
1215  // Spectral selection track is always wave
1216  auto shTrack = Track::Pointer<const WaveTrack>( pTrack );
1217  mFreqSelTrack = shTrack;
1218  mFreqSelMode = FREQ_SEL_FREE;
1219  mFreqSelPin =
1220  PositionToFrequency(shTrack.get(), false, mouseYCoordinate,
1221  trackTopEdge, trackHeight);
1223  }
1224 }
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
double mFreqSelPin
Definition: SelectHandle.h:157
enum SelectHandle::eFreqSelMode FREQ_SEL_INVALID
bool setFrequencies(double f0, double f1)
static const int UndefinedFrequency
std::weak_ptr< const WaveTrack > mFreqSelTrack
Definition: SelectHandle.h:150
void SelectHandle::StartSelection ( AudacityProject pProject)
private

Reset our selection markers.

Definition at line 1128 of file SelectHandle.cpp.

References AudacityProject::GetViewInfo(), AudacityProject::ModifyState(), mSelStart, mSelStartValid, ViewInfo::selectedRegion, and SelectedRegion::setTimes().

1129 {
1130  ViewInfo &viewInfo = pProject->GetViewInfo();
1131  mSelStartValid = true;
1132 
1134 
1135  // PRL: commented out the Sonify stuff with the TrackPanel refactor.
1136  // It was no-op anyway.
1137  //SonifyBeginModifyState();
1138  pProject->ModifyState(false);
1139  //SonifyEndModifyState();
1140 }
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
bool mSelStartValid
Definition: SelectHandle.h:134
double mSelStart
Definition: SelectHandle.h:135
void ModifyState(bool bWantsAutoSave)
Definition: Project.cpp:4747
bool setTimes(double t0, double t1)
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
void SelectHandle::StartSnappingFreqSelection ( SpectrumAnalyst analyst,
const ViewInfo viewInfo,
const WaveTrack pTrack 
)
staticprivate

Definition at line 1333 of file SelectHandle.cpp.

References SpectrumAnalyst::Calculate(), fillZero, floatSample, WaveTrack::Get(), SpectrogramSettings::GetFFTLength(), WaveTrack::GetRate(), WaveTrack::GetSpectrogramSettings(), limitSampleBufferSize(), min(), ViewInfo::selectedRegion, SpectrumAnalyst::Spectrum, SelectedRegion::t0(), SelectedRegion::t1(), WaveTrack::TimeToLongSamples(), and SpectrogramSettings::windowType.

Referenced by HandleCenterFrequencyClick(), and SnapCenterOnce().

1335 {
1336  static const size_t minLength = 8;
1337 
1338  const double rate = pTrack->GetRate();
1339 
1340  // Grab samples, just for this track, at these times
1341  std::vector<float> frequencySnappingData;
1342  const auto start =
1343  pTrack->TimeToLongSamples(viewInfo.selectedRegion.t0());
1344  const auto end =
1345  pTrack->TimeToLongSamples(viewInfo.selectedRegion.t1());
1346  const auto length =
1347  std::min(frequencySnappingData.max_size(),
1348  limitSampleBufferSize(10485760, // as in FreqWindow.cpp
1349  end - start));
1350  const auto effectiveLength = std::max(minLength, length);
1351  frequencySnappingData.resize(effectiveLength, 0.0f);
1352  pTrack->Get(
1353  reinterpret_cast<samplePtr>(&frequencySnappingData[0]),
1354  floatSample, start, length, fillZero,
1355  // Don't try to cope with exceptions, just read zeroes instead.
1356  false);
1357 
1358  // Use same settings as are now used for spectrogram display,
1359  // except, shrink the window as needed so we get some answers
1360 
1361  const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
1362  auto windowSize = settings.GetFFTLength();
1363 
1364  while(windowSize > effectiveLength)
1365  windowSize >>= 1;
1366  const int windowType = settings.windowType;
1367 
1368  analyst.Calculate(
1369  SpectrumAnalyst::Spectrum, windowType, windowSize, rate,
1370  &frequencySnappingData[0], length);
1371 
1372  // We can now throw away the sample data but we keep the spectrum.
1373 }
double t0() const
Spectrogram settings, either for one track or as defaults.
SelectedRegion selectedRegion
Definition: ViewInfo.h:160
size_t GetFFTLength() const
const SpectrogramSettings & GetSpectrogramSettings() const
Definition: WaveTrack.cpp:690
double t1() const
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: Types.h:178
bool Calculate(Algorithm alg, int windowFunc, size_t windowSize, double rate, const float *data, size_t dataLen, float *pYMin=NULL, float *pYMax=NULL, FreqGauge *progress=NULL)
int min(int a, int b)
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Definition: WaveTrack.cpp:1843
double GetRate() const
Definition: WaveTrack.cpp:398
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumCopied=nullptr) const
Definition: WaveTrack.cpp:1971

Member Data Documentation

enum SelectHandle::eFreqSelMode SelectHandle::FREQ_SEL_INVALID
private
bool SelectHandle::mAutoScrolling {}
private

Definition at line 162 of file SelectHandle.h.

Referenced by SelectHandle::TimerHandler::OnTimer().

double SelectHandle::mFreqSelPin { -1.0 }
private
std::weak_ptr<const WaveTrack> SelectHandle::mFreqSelTrack
private
std::shared_ptr<SpectrumAnalyst> SelectHandle::mFrequencySnapper
private

Definition at line 158 of file SelectHandle.h.

Referenced by HandleCenterFrequencyClick(), and MoveSnappingFreqSelection().

SelectedRegion SelectHandle::mInitialSelection {}
private

Definition at line 128 of file SelectHandle.h.

Referenced by Cancel().

int SelectHandle::mMostRecentX { -1 }
private

Definition at line 160 of file SelectHandle.h.

Referenced by SelectHandle::TimerHandler::OnTimer().

int SelectHandle::mMostRecentY { -1 }
private

Definition at line 160 of file SelectHandle.h.

std::weak_ptr<Track> SelectHandle::mpTrack
private

Definition at line 126 of file SelectHandle.h.

Referenced by AdjustSelection(), and SelectHandle::TimerHandler::OnTimer().

wxRect SelectHandle::mRect {}
private

Definition at line 127 of file SelectHandle.h.

Referenced by SelectHandle::TimerHandler::OnTimer().

int SelectHandle::mSelectionBoundary { 0 }
private

Definition at line 137 of file SelectHandle.h.

std::shared_ptr<SelectionStateChanger> SelectHandle::mSelectionStateChanger
private

Definition at line 164 of file SelectHandle.h.

Referenced by Cancel(), and IsClicked().

double SelectHandle::mSelStart { 0.0 }
private

Definition at line 135 of file SelectHandle.h.

Referenced by AdjustSelection(), AssignSelection(), and StartSelection().

bool SelectHandle::mSelStartValid {}
private

Definition at line 134 of file SelectHandle.h.

Referenced by AdjustSelection(), HandleCenterFrequencyClick(), and StartSelection().

SnapResults SelectHandle::mSnapEnd
private

Definition at line 131 of file SelectHandle.h.

Referenced by AdjustSelection(), HasSnap(), and SetUseSnap().

std::shared_ptr<SnapManager> SelectHandle::mSnapManager
private

Definition at line 130 of file SelectHandle.h.

Referenced by AdjustSelection().

SnapResults SelectHandle::mSnapStart
private

Definition at line 131 of file SelectHandle.h.

Referenced by NeedChangeHighlight().

std::shared_ptr<TimerHandler> SelectHandle::mTimerHandler
private

Definition at line 168 of file SelectHandle.h.

Referenced by Connect().

bool SelectHandle::mUseSnap { true }
private

Definition at line 132 of file SelectHandle.h.

Referenced by AdjustSelection(), HasEscape(), NeedChangeHighlight(), and SetUseSnap().

Definition at line 166 of file SelectHandle.h.


The documentation for this class was generated from the following files: