1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-01 08:29:27 +02:00

Label affordance: dragging label with bar between handles

(cherry picked from audacity commit 542a9be2eaba55605ae43a25cdfdb3635c606b0f)

Signed-off-by: akleja <storspov@gmail.com>
This commit is contained in:
Vitaly Sverchinsky 2021-07-21 19:08:00 +03:00 committed by akleja
parent d261985898
commit e293af8776
3 changed files with 43 additions and 23 deletions

View File

@ -57,6 +57,7 @@ void LabelTrackHit::OnLabelPermuted( LabelTrackEvent &e )
update( mMouseOverLabelLeft );
update( mMouseOverLabelRight );
update( mMouseOverLabel );
}
LabelGlyphHandle::LabelGlyphHandle
@ -136,14 +137,11 @@ void LabelGlyphHandle::HandleGlyphClick
if (hit.mIsAdjustingLabel)
{
double t = 0.0;
// We move if we hit the centre, we adjust one edge if we hit a chevron.
// This is if we are moving just one edge.
hit.mbIsMoving = (hit.mEdge & 4)!=0;
// No to the above! We initially expect to be moving just one edge.
hit.mbIsMoving = false;
double t = 0.0;
// When we start dragging the label(s) we don't want them to jump.
// so we calculate the displacement of the mouse from the drag center
// and use that in subsequent dragging calculations. The mouse stays
@ -190,6 +188,10 @@ void LabelGlyphHandle::HandleGlyphClick
{
t = mLabels[ hit.mMouseOverLabelLeft ].getT0();
}
else if (hit.mMouseOverLabel >= 0)
{
t = mLabels[hit.mMouseOverLabel].getT0();
}
mxMouseDisplacement = zoomInfo.TimeToPosition(t, r.x) - evt.m_x;
}
}
@ -300,16 +302,16 @@ bool LabelGlyphHandle::HandleGlyphDragRelease
const auto &mLabels = pTrack->GetLabels();
if(evt.LeftUp())
{
bool lupd = false, rupd = false;
bool updated = false;
if( hit.mMouseOverLabelLeft >= 0 ) {
auto labelStruct = mLabels[ hit.mMouseOverLabelLeft ];
lupd = labelStruct.updated;
updated |= labelStruct.updated;
labelStruct.updated = false;
pTrack->SetLabel( hit.mMouseOverLabelLeft, labelStruct );
}
if( hit.mMouseOverLabelRight >= 0 ) {
auto labelStruct = mLabels[ hit.mMouseOverLabelRight ];
rupd = labelStruct.updated;
updated |= labelStruct.updated;
labelStruct.updated = false;
pTrack->SetLabel( hit.mMouseOverLabelRight, labelStruct );
}
@ -317,7 +319,8 @@ bool LabelGlyphHandle::HandleGlyphDragRelease
hit.mIsAdjustingLabel = false;
hit.mMouseOverLabelLeft = -1;
hit.mMouseOverLabelRight = -1;
return lupd || rupd;
hit.mMouseOverLabel = -1;
return updated;
}
if(evt.Dragging())
@ -328,24 +331,26 @@ bool LabelGlyphHandle::HandleGlyphDragRelease
// to allow scrolling while dragging labels
int x = Constrain( evt.m_x + mxMouseDisplacement - r.x, 0, r.width);
// If exactly one edge is selected we allow swapping
bool bAllowSwapping =
( hit.mMouseOverLabelLeft >=0 ) !=
( hit.mMouseOverLabelRight >= 0);
double fNewX = zoomInfo.PositionToTime(x, 0);
// Moving the whole ranged label
if (hit.mMouseOverLabel != -1)
{
MayMoveLabel(hit.mMouseOverLabel, -1, fNewX);
}
// If we're on the 'dot' and nowe're moving,
// Though shift-down inverts that.
// and if both edges the same, then we're always moving the label.
bool bLabelMoving = hit.mbIsMoving;
bLabelMoving ^= evt.ShiftDown();
bLabelMoving |= ( hit.mMouseOverLabelLeft == hit.mMouseOverLabelRight );
double fNewX = zoomInfo.PositionToTime(x, 0);
if( bLabelMoving )
else if((hit.mMouseOverLabelLeft == hit.mMouseOverLabelRight) || evt.ShiftDown())
{
MayMoveLabel( hit.mMouseOverLabelLeft, -1, fNewX );
MayMoveLabel( hit.mMouseOverLabelRight, +1, fNewX );
}
else
{
// If exactly one edge is selected we allow swapping
bool bAllowSwapping =
(hit.mMouseOverLabelLeft >= 0) !=
(hit.mMouseOverLabelRight >= 0);
MayAdjustLabel( hit, hit.mMouseOverLabelLeft, -1, bAllowSwapping, fNewX );
MayAdjustLabel( hit, hit.mMouseOverLabelRight, +1, bAllowSwapping, fNewX );
}

View File

@ -35,6 +35,8 @@ struct LabelTrackHit
~LabelTrackHit();
int mEdge{};
//This one is to distinguish ranged label from point label
int mMouseOverLabel{ -1 }; /// Keeps track of which (ranged) label the mouse is currently over.
int mMouseOverLabelLeft{ -1 }; /// Keeps track of which left label the mouse is currently over.
int mMouseOverLabelRight{ -1 }; /// Keeps track of which right label the mouse is currently over.
bool mbIsMoving {};

View File

@ -851,6 +851,8 @@ void LabelTrackView::Draw
highlight = highlightTrack && target->GetLabelNum() == i;
#endif
bool selected = GetSelectedIndex( project ) == i;
dc.SetBrush(pHit && pHit->mMouseOverLabel == i
? AColor::labelTextEditBrush : AColor::labelTextNormalBrush);
DrawBar(dc, labelStruct, r);
if( selected )
@ -1194,11 +1196,23 @@ void LabelTrackView::OverGlyph(
//If not over a label, reset it
hit.mMouseOverLabelLeft = -1;
hit.mMouseOverLabelRight = -1;
hit.mMouseOverLabel = -1;
hit.mEdge = 0;
const auto pTrack = &track;
const auto &mLabels = pTrack->GetLabels();
{ int i = -1; for (const auto &labelStruct : mLabels) { ++i;
// give text box better priority for selecting
// reset selection state
if (OverTextBox(&labelStruct, x, y))
{
result = 0;
hit.mMouseOverLabel = -1;
hit.mMouseOverLabelLeft = -1;
hit.mMouseOverLabelRight = -1;
break;
}
//over left or right selection bound
//Check right bound first, since it is drawn after left bound,
//so give it precedence for matching/highlighting.
@ -1229,13 +1243,12 @@ void LabelTrackView::OverGlyph(
result |= 4;
result |= 1;
}
// give text box better priority for selecting
if(OverTextBox(&labelStruct, x, y))
else if (x >= labelStruct.x && x <= labelStruct.x1 &&
abs(y - (labelStruct.y + mTextHeight / 2)) < d1)
{
result = 0;
hit.mMouseOverLabel = i;
result = 3;
}
}}
hit.mEdge = result;
}