Fix poor synchronization between mouse and keyboard modifications to the selection

Combining Shift+Up/Down (or Home/End or Page Up/Page Down) with
shift-clicking had very odd results due to that they used separate
variables to decide where to extend from (and even when only one was
used they were handled incorrectly in some cases).

Closes #1311.

Originally committed to SVN as r6355.
This commit is contained in:
Thomas Goyne 2012-01-25 04:59:17 +00:00
parent e6d86a1af4
commit 26c3e13340
2 changed files with 31 additions and 42 deletions

View file

@ -89,7 +89,6 @@ static inline void set_difference(const S1 &src1, const S2 &src2, D &dst) {
BaseGrid::BaseGrid(wxWindow* parent, agi::Context *context, const wxSize& size, long style, const wxString& name) BaseGrid::BaseGrid(wxWindow* parent, agi::Context *context, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, -1, wxDefaultPosition, size, style, name) : wxWindow(parent, -1, wxDefaultPosition, size, style, name)
, lineHeight(1) // non-zero to avoid div by 0 , lineHeight(1) // non-zero to avoid div by 0
, lastRow(-1)
, holding(false) , holding(false)
, scrollBar(new wxScrollBar(this, GRID_SCROLLBAR, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL)) , scrollBar(new wxScrollBar(this, GRID_SCROLLBAR, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL))
, bmp(0) , bmp(0)
@ -349,8 +348,6 @@ void BaseGrid::EndBatch() {
} }
void BaseGrid::MakeCellVisible(int row, int col, bool center) { void BaseGrid::MakeCellVisible(int row, int col, bool center) {
lastRow = row;
int w = 0; int w = 0;
int h = 0; int h = 0;
GetClientSize(&w,&h); GetClientSize(&w,&h);
@ -722,51 +719,45 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Click // Click
if ((click || holding || dclick) && dlg) { if ((click || holding || dclick) && dlg) {
int old_extend = extendRow;
SetActiveLine(dlg);
// Toggle selected // Toggle selected
if (click && ctrl && !shift && !alt) { if (click && ctrl && !shift && !alt) {
bool isSel = !!selection.count(dlg); bool isSel = !!selection.count(dlg);
if (isSel && selection.size() == 1) return; if (isSel && selection.size() == 1) return;
SelectRow(row,true,!isSel); SelectRow(row, true, !isSel);
if (dlg == GetActiveLine()) {
SetActiveLine(GetDialogue(GetFirstSelRow()));
}
lastRow = row;
return; return;
} }
// Normal click // Normal click
if ((click || dclick) && !shift && !ctrl && !alt) { if ((click || dclick) && !shift && !ctrl && !alt) {
SetActiveLine(dlg);
if (dclick) context->videoController->JumpToTime(dlg->Start); if (dclick) context->videoController->JumpToTime(dlg->Start);
SelectRow(row,false); SelectRow(row, false);
lastRow = row;
return; return;
} }
// Keep selection // Change active line only
if (click && !shift && !ctrl && alt) { if (click && !shift && !ctrl && alt) {
SetActiveLine(dlg);
return; return;
} }
// Block select // Block select
if ((click && shift && !alt) || (holding && !ctrl && !alt && !shift)) { if ((click && shift && !alt) || (holding && !ctrl && !alt && !shift)) {
if (lastRow != -1) { extendRow = old_extend;
// Set boundaries int i1 = row;
int i1 = row; int i2 = extendRow;
int i2 = lastRow;
if (i1 > i2) {
std::swap(i1, i2);
}
// Toggle each if (i1 > i2)
Selection newsel; std::swap(i1, i2);
if (ctrl) newsel = selection;
for (int i=i1;i<=i2;i++) { // Toggle each
newsel.insert(GetDialogue(i)); Selection newsel;
} if (ctrl) newsel = selection;
SetSelectedSet(newsel); for (int i = i1; i <= i2; i++) {
newsel.insert(GetDialogue(i));
} }
SetSelectedSet(newsel);
return; return;
} }
@ -1010,38 +1001,36 @@ void BaseGrid::OnKeyDown(wxKeyEvent &event) {
// Moving // Moving
if (dir) { if (dir) {
int old_extend = extendRow;
int next = mid(0, GetDialogueIndex(active_line) + dir * step, GetRows() - 1);
SetActiveLine(GetDialogue(next));
// Move selection // Move selection
if (!ctrl && !shift && !alt) { if (!ctrl && !shift && !alt) {
int next = mid(0, extendRow + dir * step, GetRows() - 1);
SetActiveLine(GetDialogue(next));
SelectRow(next); SelectRow(next);
return; return;
} }
// Move active only // Move active only
else if (alt && !shift && !ctrl) { if (alt && !shift && !ctrl) {
int next = mid(0, GetDialogueIndex(GetActiveLine()) + dir * step, GetRows() - 1);
SetActiveLine(GetDialogue(next));
Refresh(false); Refresh(false);
return; return;
} }
// Shift-selection // Shift-selection
else if (shift && !ctrl && !alt) { if (shift && !ctrl && !alt) {
extendRow = mid(0, extendRow + dir * step, GetRows() - 1); extendRow = old_extend;
// Set range // Set range
int begin = GetDialogueIndex(GetActiveLine()); int begin = next;
int end = extendRow; int end = extendRow;
if (end < begin) { if (end < begin)
std::swap(begin, end); std::swap(begin, end);
}
// Select range // Select range
Selection newsel; Selection newsel;
for (int i = begin; i <= end; i++) { for (int i = begin; i <= end; i++)
newsel.insert(GetDialogue(i)); newsel.insert(GetDialogue(i));
}
SetSelectedSet(newsel); SetSelectedSet(newsel);
MakeCellVisible(extendRow, 0, false); MakeCellVisible(extendRow, 0, false);

View file

@ -66,14 +66,14 @@ typedef SelectionListener<AssDialogue> SubtitleSelectionListener;
/// DOCME /// DOCME
class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> { class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
int lineHeight; ///< Height of a line in pixels in the current font int lineHeight; ///< Height of a line in pixels in the current font
int lastRow; ///< ?
bool holding; ///< Is a drag selection in process? bool holding; ///< Is a drag selection in process?
wxFont font; ///< Current grid font wxFont font; ///< Current grid font
wxScrollBar *scrollBar; ///< The grid's scrollbar wxScrollBar *scrollBar; ///< The grid's scrollbar
wxBitmap *bmp; ///< Back buffer which the grid is rendered into wxBitmap *bmp; ///< Back buffer which the grid is rendered into
bool byFrame; ///< Should times be displayed as frame numbers bool byFrame; ///< Should times be displayed as frame numbers
/// Row from which the selection shrinks/grows from when selecting via the /// Row from which the selection shrinks/grows from when selecting via the
/// keyboard. Equal to the active row except for when using shift+up/down. /// keyboard, shift-clicking or dragging
int extendRow; int extendRow;
Selection selection; ///< Currently selected lines Selection selection; ///< Currently selected lines