mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-04 22:49:07 +02:00
All UIHandle::Preview() return same cursors, messages as HitTest...
... except TrackSelectHandle. Cursor changes to a hand only after button-down. HitTests give a UIHandle, whenever they also give any cursor or status, even when it's unsafe to click and drag; Click override is reponsible for cancelling. SelectHandle::Preview introduces much duplication, but the original in the hit test will later be deleted.
This commit is contained in:
parent
3a8280c562
commit
d2fbca83b2
@ -155,10 +155,12 @@ UIHandle::Result StretchHandle::Click
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if ( unsafe )
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
|
||||
if (unsafe ||
|
||||
event.LeftDClick() ||
|
||||
if (event.LeftDClick() ||
|
||||
!event.LeftDown() ||
|
||||
evt.pCell == NULL)
|
||||
return Cancelled;
|
||||
|
@ -50,12 +50,7 @@ HitTestPreview CutlineHandle::HitPreview(bool cutline, bool unsafe)
|
||||
HitTestResult CutlineHandle::HitAnywhere(const AudacityProject *pProject, bool cutline)
|
||||
{
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return {
|
||||
HitPreview(cutline, unsafe),
|
||||
(unsafe
|
||||
? NULL
|
||||
: &Instance())
|
||||
};
|
||||
return { HitPreview(cutline, unsafe), &Instance() };
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -131,6 +126,11 @@ CutlineHandle::~CutlineHandle()
|
||||
UIHandle::Result CutlineHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if ( unsafe )
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
const auto pTrack = static_cast<Track*>(evt.pCell.get());
|
||||
@ -138,12 +138,8 @@ UIHandle::Result CutlineHandle::Click
|
||||
// Can affect the track by merging clips, expanding a cutline, or
|
||||
// deleting a cutline.
|
||||
// All the change is done at button-down. Button-up just commits the undo item.
|
||||
using namespace RefreshCode;
|
||||
|
||||
/// Someone has just clicked the mouse. What do we do?
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if (unsafe)
|
||||
return Cancelled;
|
||||
|
||||
WaveTrackLocation capturedTrackLocation;
|
||||
|
||||
@ -222,9 +218,10 @@ UIHandle::Result CutlineHandle::Drag
|
||||
}
|
||||
|
||||
HitTestPreview CutlineHandle::Preview
|
||||
(const TrackPanelMouseState &, const AudacityProject *)
|
||||
(const TrackPanelMouseState &, const AudacityProject *pProject)
|
||||
{
|
||||
return HitPreview(mbCutline, false);
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return HitPreview( mbCutline, unsafe );
|
||||
}
|
||||
|
||||
UIHandle::Result CutlineHandle::Release
|
||||
|
@ -67,12 +67,7 @@ HitTestResult SampleHandle::HitAnywhere
|
||||
(const wxMouseState &state, const AudacityProject *pProject)
|
||||
{
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return {
|
||||
HitPreview(state, pProject, unsafe),
|
||||
(unsafe
|
||||
? NULL
|
||||
: &Instance())
|
||||
};
|
||||
return { HitPreview(state, pProject, unsafe), &Instance() };
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -206,17 +201,17 @@ namespace {
|
||||
UIHandle::Result SampleHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if ( unsafe )
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const wxRect &rect = evt.rect;
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
const auto pTrack = std::static_pointer_cast<WaveTrack>(evt.pCell);
|
||||
|
||||
using namespace RefreshCode;
|
||||
|
||||
/// Someone has just clicked the mouse. What do we do?
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if (unsafe)
|
||||
return Cancelled;
|
||||
if (!IsSampleEditingPossible(
|
||||
event, rect, viewInfo, pTrack.get(), rect.width))
|
||||
return Cancelled;
|
||||
@ -419,7 +414,8 @@ UIHandle::Result SampleHandle::Drag
|
||||
HitTestPreview SampleHandle::Preview
|
||||
(const TrackPanelMouseState &st, const AudacityProject *pProject)
|
||||
{
|
||||
return HitPreview(st.state, pProject, false);
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return HitPreview(st.state, pProject, unsafe);
|
||||
}
|
||||
|
||||
UIHandle::Result SampleHandle::Release
|
||||
|
@ -54,12 +54,7 @@ HitTestPreview EnvelopeHandle::HitPreview(const AudacityProject *pProject, bool
|
||||
HitTestResult EnvelopeHandle::HitAnywhere(const AudacityProject *pProject)
|
||||
{
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return {
|
||||
HitPreview(pProject, unsafe),
|
||||
(unsafe
|
||||
? NULL
|
||||
: &Instance())
|
||||
};
|
||||
return { HitPreview(pProject, unsafe), &Instance() };
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -182,15 +177,15 @@ EnvelopeHandle::~EnvelopeHandle()
|
||||
UIHandle::Result EnvelopeHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
const auto pTrack = static_cast<Track*>(evt.pCell.get());
|
||||
|
||||
using namespace RefreshCode;
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if ( unsafe )
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
const auto pTrack = static_cast<Track*>(evt.pCell.get());
|
||||
|
||||
if (pTrack->GetKind() == Track::Wave) {
|
||||
WaveTrack *const wt = static_cast<WaveTrack*>(pTrack);
|
||||
if (wt->GetDisplay() != WaveTrack::Waveform)
|
||||
@ -257,7 +252,8 @@ UIHandle::Result EnvelopeHandle::Drag
|
||||
HitTestPreview EnvelopeHandle::Preview
|
||||
(const TrackPanelMouseState &, const AudacityProject *pProject)
|
||||
{
|
||||
return HitPreview(pProject, false);
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return HitPreview(pProject, unsafe);
|
||||
}
|
||||
|
||||
UIHandle::Result EnvelopeHandle::Release
|
||||
|
@ -49,6 +49,11 @@ enum {
|
||||
|
||||
// #define SPECTRAL_EDITING_ESC_KEY
|
||||
|
||||
bool SelectHandle::IsClicked() const
|
||||
{
|
||||
return mSelectionStateChanger.get();
|
||||
}
|
||||
|
||||
SelectHandle::SelectHandle()
|
||||
{
|
||||
}
|
||||
@ -888,14 +893,95 @@ UIHandle::Result SelectHandle::Drag
|
||||
}
|
||||
|
||||
HitTestPreview SelectHandle::Preview
|
||||
(const TrackPanelMouseState &, const AudacityProject *pProject)
|
||||
(const TrackPanelMouseState &st, const AudacityProject *pProject)
|
||||
{
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return {};
|
||||
|
||||
wxString tip;
|
||||
wxCursor *pCursor;
|
||||
wxCursor *pCursor = SelectCursor();
|
||||
if ( IsClicked() )
|
||||
// Use same cursor as at the clck
|
||||
SetTipAndCursorForBoundary
|
||||
(SelectionBoundary(mSelectionBoundary),
|
||||
(mFreqSelMode == FREQ_SEL_SNAPPING_CENTER),
|
||||
tip, pCursor);
|
||||
else {
|
||||
// Choose one of many cursors for mouse-over
|
||||
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
|
||||
const bool bMultiToolMode =
|
||||
pProject->GetToolsToolBar()->IsDown(multiTool);
|
||||
|
||||
//In Multi-tool mode, give multitool prompt if no-special-hit.
|
||||
if (bMultiToolMode) {
|
||||
// Look up the current key binding for Preferences.
|
||||
// (Don't assume it's the default!)
|
||||
wxString keyStr
|
||||
(pProject->GetCommandManager()->GetKeyFromName(wxT("Preferences")));
|
||||
if (keyStr.IsEmpty())
|
||||
// No keyboard preference defined for opening Preferences dialog
|
||||
/* i18n-hint: These are the names of a menu and a command in that menu */
|
||||
keyStr = _("Edit, Preferences...");
|
||||
else
|
||||
keyStr = KeyStringDisplay(keyStr);
|
||||
/* i18n-hint: %s is usually replaced by "Ctrl+P" for Windows/Linux, "Command+," for Mac */
|
||||
tip = wxString::Format(
|
||||
_("Multi-Tool Mode: %s for Mouse and Keyboard Preferences."),
|
||||
keyStr.c_str());
|
||||
// Later in this function we may point to some other string instead.
|
||||
if (!pTrack->GetSelected() ||
|
||||
!viewInfo.bAdjustSelectionEdges)
|
||||
;
|
||||
else {
|
||||
const auto &state = st.state;
|
||||
const wxRect &rect = st.rect;
|
||||
const bool bShiftDown = state.ShiftDown();
|
||||
const bool bCtrlDown = state.ControlDown();
|
||||
const bool bModifierDown = bShiftDown || bCtrlDown;
|
||||
|
||||
// If not shift-down and not snapping center, then
|
||||
// choose boundaries only in snapping tolerance,
|
||||
// and may choose center.
|
||||
SelectionBoundary boundary =
|
||||
ChooseBoundary(viewInfo, state, pTrack.get(), rect, !bModifierDown, !bModifierDown);
|
||||
|
||||
SetTipAndCursorForBoundary(boundary, !bShiftDown, tip, pCursor);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This is a vestige of an idea in the prototype version.
|
||||
// Center would snap without mouse button down, click would pin the center
|
||||
// and drag width.
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
if ((mFreqSelMode == FREQ_SEL_SNAPPING_CENTER) &&
|
||||
isSpectralSelectionTrack(pTrack)) {
|
||||
// Not shift-down, but center frequency snapping toggle is on
|
||||
tip = _("Click and drag to set frequency bandwidth.");
|
||||
pCursor = &*envelopeCursor;
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!pTrack->GetSelected() || !viewInfo.bAdjustSelectionEdges)
|
||||
;
|
||||
else {
|
||||
const auto &state = st.state;
|
||||
const wxRect &rect = st.rect;
|
||||
const bool bShiftDown = state.ShiftDown();
|
||||
const bool bCtrlDown = state.ControlDown();
|
||||
const bool bModifierDown = bShiftDown || bCtrlDown;
|
||||
SelectionBoundary boundary = ChooseBoundary(
|
||||
viewInfo, state, pTrack.get(), rect, !bModifierDown, !bModifierDown);
|
||||
SetTipAndCursorForBoundary(boundary, !bShiftDown, tip, pCursor);
|
||||
}
|
||||
|
||||
MaySetOnDemandTip(pTrack.get(), tip);
|
||||
}
|
||||
if (tip == "") {
|
||||
const auto ttb = pProject->GetToolsToolBar();
|
||||
if (ttb)
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
|
||||
virtual ~SelectHandle();
|
||||
|
||||
bool IsClicked() const;
|
||||
|
||||
virtual Result Click
|
||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject);
|
||||
|
||||
|
@ -54,12 +54,7 @@ HitTestResult TimeShiftHandle::HitAnywhere(const AudacityProject *pProject)
|
||||
// After all that, it still may be unsafe to drag.
|
||||
// Even if so, make an informative cursor change from default to "banned."
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return {
|
||||
HitPreview(pProject, unsafe),
|
||||
(unsafe
|
||||
? NULL
|
||||
: &Instance())
|
||||
};
|
||||
return { HitPreview(pProject, unsafe), &Instance() };
|
||||
}
|
||||
|
||||
HitTestResult TimeShiftHandle::HitTest
|
||||
@ -413,18 +408,17 @@ void TimeShiftHandle::DoSlideHorizontal
|
||||
UIHandle::Result TimeShiftHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if ( unsafe )
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const wxRect &rect = evt.rect;
|
||||
const ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
|
||||
const auto pTrack = std::static_pointer_cast<Track>(evt.pCell);
|
||||
|
||||
using namespace RefreshCode;
|
||||
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
if (unsafe)
|
||||
return Cancelled;
|
||||
|
||||
TrackList *const trackList = pProject->GetTracks();
|
||||
|
||||
mClipMoveState.clear();
|
||||
@ -771,7 +765,10 @@ UIHandle::Result TimeShiftHandle::Drag
|
||||
HitTestPreview TimeShiftHandle::Preview
|
||||
(const TrackPanelMouseState &, const AudacityProject *pProject)
|
||||
{
|
||||
return HitPreview(pProject, false);
|
||||
// After all that, it still may be unsafe to drag.
|
||||
// Even if so, make an informative cursor change from default to "banned."
|
||||
const bool unsafe = pProject->IsAudioActive();
|
||||
return HitPreview(pProject, unsafe);
|
||||
}
|
||||
|
||||
UIHandle::Result TimeShiftHandle::Release
|
||||
|
@ -83,6 +83,9 @@ TrackSelectHandle::~TrackSelectHandle()
|
||||
UIHandle::Result TrackSelectHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
// If unsafe to drag, still, it does harmlessly change the selected track
|
||||
// set on button down.
|
||||
|
||||
using namespace RefreshCode;
|
||||
Result result = RefreshNone;
|
||||
|
||||
@ -165,20 +168,31 @@ UIHandle::Result TrackSelectHandle::Drag
|
||||
HitTestPreview TrackSelectHandle::Preview
|
||||
(const TrackPanelMouseState &, const AudacityProject *project)
|
||||
{
|
||||
// Note that this differs from HitPreview.
|
||||
|
||||
const auto trackCount = project->GetTrackPanel()->GetTrackCount();
|
||||
if (mpTrack) {
|
||||
// Has been clicked
|
||||
static auto disabledCursor =
|
||||
::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16);
|
||||
static wxCursor rearrangeCursor{ wxCURSOR_HAND };
|
||||
|
||||
const bool unsafe = GetActiveProject()->IsAudioActive();
|
||||
return {
|
||||
Message(project->GetTrackPanel()->GetTrackCount()),
|
||||
Message(trackCount),
|
||||
(unsafe
|
||||
? &*disabledCursor
|
||||
: &rearrangeCursor)
|
||||
};
|
||||
}
|
||||
else {
|
||||
// Only mouse-over
|
||||
// Don't test safety, because the click to change selection is allowed
|
||||
static wxCursor arrowCursor{ wxCURSOR_ARROW };
|
||||
return {
|
||||
Message(trackCount),
|
||||
&arrowCursor
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
UIHandle::Result TrackSelectHandle::Release
|
||||
(const TrackPanelMouseEvent &, AudacityProject *, wxWindow *)
|
||||
|
Loading…
x
Reference in New Issue
Block a user