1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-04 14:39:08 +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:
Paul Licameli 2017-06-18 00:32:30 -04:00
parent 3a8280c562
commit d2fbca83b2
8 changed files with 159 additions and 69 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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)
{
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());
using namespace RefreshCode;
const bool unsafe = pProject->IsAudioActive();
if (unsafe)
return Cancelled;
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

View File

@ -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;
SetTipAndCursorForBoundary
(SelectionBoundary(mSelectionBoundary),
(mFreqSelMode == FREQ_SEL_SNAPPING_CENTER),
tip, 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)

View File

@ -45,6 +45,8 @@ public:
virtual ~SelectHandle();
bool IsClicked() const;
virtual Result Click
(const TrackPanelMouseEvent &event, AudacityProject *pProject);

View File

@ -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

View File

@ -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,19 +168,30 @@ 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 };
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()),
(unsafe
? &*disabledCursor
: &rearrangeCursor)
};
const bool unsafe = GetActiveProject()->IsAudioActive();
return {
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