1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-23 15:50:05 +02:00

Bug1443: Various odd behavior of label text editor, fixed...

... And label track selection code is simpler to understand, without delayed
side effects happening during drawing.

Left and right arrow keys collapse text range selection correctly
Shift-click adjusts the end of selection nearest the pick
Right (and middle) click and drag do not affect the selection
Copying empty selection has no effect on the clipboard
Left-drag behaves independently of previous selection state
This commit is contained in:
Paul Licameli 2016-07-11 13:59:29 -04:00
parent 5648023cf3
commit cb3e5e6d4f
2 changed files with 60 additions and 114 deletions

View File

@ -269,7 +269,6 @@ void LabelTrack::WarpLabels(const TimeWarper &warper) {
void LabelTrack::ResetFlags()
{
mDragXPos = -1;
mInitialCursorPos = 1;
mCurrentCursorPos = 1;
mRightDragging = false;
@ -522,8 +521,6 @@ LabelStruct::LabelStruct(const SelectedRegion &region,
: selectedRegion(region)
, title(aTitle)
{
changeInitialMouseXPos = true;
highlighted = false;
updated = false;
width = 0;
x = 0;
@ -541,8 +538,6 @@ LabelStruct::LabelStruct(const SelectedRegion &region,
// Overwrite the times
selectedRegion.setTimes(t0, t1);
changeInitialMouseXPos = true;
highlighted = false;
updated = false;
width = 0;
x = 0;
@ -694,9 +689,6 @@ void LabelStruct::DrawTextBox(wxDC & dc, const wxRect & r) const
void LabelStruct::DrawHighlight
( wxDC & dc, int xPos1, int xPos2, int charHeight) const
{
highlighted = true;
changeInitialMouseXPos = false;
wxPen curPen = dc.GetPen();
curPen.SetColour(wxString(wxT("BLUE")));
wxBrush curBrush = dc.GetBrush();
@ -826,7 +818,7 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r,
}}
// Draw highlights
if ((mDragXPos != -1) && (mSelIndex >= 0 ))
if ((mInitialCursorPos != mCurrentCursorPos) && (mSelIndex >= 0 ))
{
int xpos1, xpos2;
CalcHighlightXs(&xpos1, &xpos2);
@ -866,11 +858,11 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r,
}
}
/// Set the cursor position according to x position of mouse
/// uses GetTextExtent to find the character position
/// corresponding to the x pixel position.
void LabelTrack::SetCurrentCursorPosition(int xPos)
int LabelTrack::FindCurrentCursorPosition(int xPos)
{
int result = -1;
wxMemoryDC dc;
if(msFont.Ok())
dc.SetFont(msFont);
@ -898,7 +890,7 @@ void LabelTrack::SetCurrentCursorPosition(int xPos)
if (xPos <= bound)
{
// Found
mCurrentCursorPos = charIndex - 1;
result = charIndex - 1;
finished = true;
}
else
@ -908,10 +900,16 @@ void LabelTrack::SetCurrentCursorPosition(int xPos)
}
}
if (!finished)
{
// Cursor should be in the last position
mCurrentCursorPos = length;
}
result = length;
return result;
}
/// Set the cursor position according to x position of mouse
void LabelTrack::SetCurrentCursorPosition(int xPos)
{
mCurrentCursorPos = FindCurrentCursorPosition(xPos);
}
void LabelTrack::calculateFontHeight(wxDC & dc) const
@ -936,8 +934,6 @@ bool LabelTrack::IsTextSelected()
{
if (mSelIndex == -1)
return false;
if (!mLabels[mSelIndex].highlighted)
return false;
if (mCurrentCursorPos == mInitialCursorPos)
return false;
return true;
@ -993,14 +989,15 @@ bool LabelTrack::CopySelectedText()
return false;
const auto &labelStruct = mLabels[mSelIndex];
if (!labelStruct.highlighted)
return false;
int init = mInitialCursorPos;
int cur = mCurrentCursorPos;
if (init > cur)
std::swap(init, cur);
if (init == cur)
return false;
// data for copying
wxString data = labelStruct.title.Mid(init, cur-init);
@ -1043,12 +1040,9 @@ bool LabelTrack::PasteSelectedText(double sel0, double sel1)
auto &labelStruct = mLabels[mSelIndex];
auto &title = labelStruct.title;
int cur = mCurrentCursorPos, init = cur;
if (labelStruct.highlighted) {
init = mInitialCursorPos;
if (init > cur)
std::swap(init, cur);
}
int cur = mCurrentCursorPos, init = mInitialCursorPos;
if (init > cur)
std::swap(init, cur);
left = title.Left(init);
if (cur < (int)title.Length())
right = title.Mid(cur);
@ -1493,20 +1487,9 @@ void LabelTrack::HandleTextDragRelease(const wxMouseEvent & evt)
if(evt.Dragging())
{
// if dragging happens in text box
// end dragging x position in pixels
// set flag to update current cursor position
mDragXPos = evt.m_x;
// for preventing dragging glygh from changing current cursor position
// set end dragging position to current cursor position
SetCurrentCursorPosition(mDragXPos);
// if it's an invalid dragging, disable displaying
if (mRightDragging) {
mDragXPos = -1;
mRightDragging = false;
}
if (!mRightDragging)
// Update drag end
SetCurrentCursorPosition(evt.m_x);
return;
}
@ -1573,20 +1556,33 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
return;
}
// disable displaying if left button is down
if (evt.LeftDown())
mDragXPos = -1;
mSelIndex = OverATextBox(evt.m_x, evt.m_y);
if (mSelIndex != -1) {
auto &labelStruct = mLabels[mSelIndex];
*newSel = labelStruct.selectedRegion;
SetCurrentCursorPosition(evt.m_x);
// for preventing from resetting by shift+mouse left button
if (labelStruct.changeInitialMouseXPos)
mInitialCursorPos = mCurrentCursorPos;
mDrawCursor = true;
if (evt.LeftDown()) {
// Find the NEW drag end
auto position = FindCurrentCursorPosition(evt.m_x);
if (evt.ShiftDown()) {
// Set the drag anchor at the end of the previous selection
// that is farther from the NEW drag end
if (abs(position - mCurrentCursorPos) >
abs(position - mInitialCursorPos))
mInitialCursorPos = mCurrentCursorPos;
}
else
mInitialCursorPos = position;
mCurrentCursorPos = position;
mDrawCursor = true;
mRightDragging = false;
}
else
// Actually this might be right or middle down
mRightDragging = true;
// reset the highlight indicator
wxRect highlightedRect;
@ -1600,28 +1596,8 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
xpos1, labelStruct.y - mFontHeight / 2,
(int)(xpos2 - xpos1 + 0.5), mFontHeight
};
// reset when left button is down
if (evt.LeftDown())
labelStruct.highlighted = false;
// reset when right button is down outside text box
if (evt.RightDown())
{
if (!highlightedRect.Contains(evt.m_x, evt.m_y))
{
mCurrentCursorPos = mInitialCursorPos = 0;
labelStruct.highlighted = false;
}
}
// set changeInitialMouseXPos flag
labelStruct.changeInitialMouseXPos = true;
}
// disable displaying if right button is down outside text box
if (evt.RightDown()
&& !highlightedRect.Contains(evt.m_x, evt.m_y))
mDragXPos = -1;
// Middle click on GTK: paste from primary selection
#if defined(__WXGTK__) && (HAVE_GTK)
if (evt.MiddleDown()) {
@ -1634,16 +1610,6 @@ void LabelTrack::HandleClick(const wxMouseEvent & evt,
*newSel = SelectedRegion(t, t);
}
#endif
// handle shift+mouse left button
if (evt.ShiftDown()) {
// if the mouse is clicked in text box, set flags
mDragXPos = evt.m_x;
// for preventing dragging glygh from changing current cursor position
// set end dragging position to current cursor position
SetCurrentCursorPosition(evt.m_x);
}
}
#if defined(__WXGTK__) && (HAVE_GTK)
@ -1732,9 +1698,8 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
if (len > 0)
{
// IF there are some highlighted letters, THEN DELETE them
if (labelStruct.highlighted) {
if (mInitialCursorPos != mCurrentCursorPos)
RemoveSelectedText();
}
else
{
// DELETE one letter
@ -1763,9 +1728,8 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
if (len > 0)
{
// if there are some highlighted letters, DELETE them
if (labelStruct.highlighted) {
if (mInitialCursorPos != mCurrentCursorPos)
RemoveSelectedText();
}
else
{
// DELETE one letter
@ -1789,11 +1753,9 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
// Move cursor to beginning of label
mCurrentCursorPos = 0;
if (mods == wxMOD_SHIFT)
mDragXPos = 0;
else {
mDragXPos = -1;
;
else
mInitialCursorPos = mCurrentCursorPos;
}
break;
case WXK_END:
@ -1801,11 +1763,9 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
// Move cursor to end of label
mCurrentCursorPos = (int)title.length();
if (mods == wxMOD_SHIFT)
mDragXPos = 0;
else {
mDragXPos = -1;
;
else
mInitialCursorPos = mCurrentCursorPos;
}
break;
case WXK_LEFT:
@ -1814,11 +1774,10 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
if (mCurrentCursorPos > 0) {
mCurrentCursorPos--;
if (mods == wxMOD_SHIFT)
mDragXPos = 0;
else {
mDragXPos = -1;
mInitialCursorPos = mCurrentCursorPos;
}
;
else
mInitialCursorPos = mCurrentCursorPos =
std::min(mInitialCursorPos, mCurrentCursorPos);
}
break;
@ -1828,11 +1787,10 @@ bool LabelTrack::OnKeyDown(SelectedRegion &newSel, wxKeyEvent & event)
if (mCurrentCursorPos < (int)title.length()) {
mCurrentCursorPos++;
if (mods == wxMOD_SHIFT)
mDragXPos = 0;
else {
mDragXPos = -1;
mInitialCursorPos = mCurrentCursorPos;
}
;
else
mInitialCursorPos = mCurrentCursorPos =
std::max(mInitialCursorPos, mCurrentCursorPos);
}
break;
@ -1984,9 +1942,8 @@ bool LabelTrack::OnChar(SelectedRegion &WXUNUSED(newSel), wxKeyEvent & event)
auto &title = labelStruct.title;
// Test if cursor is in the end of string or not
if (labelStruct.highlighted) {
if (mInitialCursorPos != mCurrentCursorPos)
RemoveSelectedText();
}
if (mCurrentCursorPos < (int)title.length()) {
// Get substring on the righthand side of cursor
@ -2048,9 +2005,6 @@ void LabelTrack::ShowContextMenu()
parent->PopupMenu(&menu, x, ls->y + (mIconHeight / 2) - 1);
}
// it's an invalid dragging event
SetWrongDragging(true);
}
void LabelTrack::OnContextMenu(wxCommandEvent & evt)
@ -2126,8 +2080,6 @@ void LabelTrack::RemoveSelectedText()
title = left + right;
mInitialCursorPos = mCurrentCursorPos = left.Length();
labelStruct.highlighted = false;
mDragXPos = -1;
}
void LabelTrack::Unselect()

View File

@ -96,8 +96,6 @@ public:
mutable int xText; /// Pixel position of left hand side of text box
mutable int y; /// Pixel position of label.
mutable bool highlighted; /// if the text is highlighted
mutable bool changeInitialMouseXPos; /// flag to change initial mouse X pos
bool updated; /// flag to tell if the label times were updated
};
@ -180,9 +178,6 @@ class AUDACITY_DLL_API LabelTrack final : public Track
bool PasteSelectedText(double sel0, double sel1);
static bool IsTextClipSupported();
// methods to set flags
void SetWrongDragging(bool rightFlag) { mRightDragging = rightFlag; }
void HandleClick(const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
SelectedRegion *newSel);
bool HandleGlyphDragRelease(const wxMouseEvent & evt, wxRect & r, const ZoomInfo &zoomInfo,
@ -263,8 +258,6 @@ class AUDACITY_DLL_API LabelTrack final : public Track
static int mFontHeight;
int mCurrentCursorPos; /// current cursor position
int mInitialCursorPos; /// initial cursor position
int mDragXPos; /// end X pos of dragging
/// in text box
bool mRightDragging; /// flag to tell if it's a valid dragging
bool mDrawCursor; /// flag to tell if drawing the
@ -279,6 +272,7 @@ class AUDACITY_DLL_API LabelTrack final : public Track
void ComputeTextPosition(const wxRect & r, int index) const;
public:
int FindCurrentCursorPosition(int xPos);
void SetCurrentCursorPosition(int xPos);
private: