Overhaul draggable selection rectangle logic
The cursor always forms one corner of the selection area. The area can also be selected with the keyboard using Shift and the arrow keys.
This commit is contained in:
89
document.cpp
89
document.cpp
@@ -34,6 +34,7 @@ TeletextDocument::TeletextDocument()
|
|||||||
m_undoStack = new QUndoStack(this);
|
m_undoStack = new QUndoStack(this);
|
||||||
m_cursorRow = 1;
|
m_cursorRow = 1;
|
||||||
m_cursorColumn = 0;
|
m_cursorColumn = 0;
|
||||||
|
m_selectionCornerRow = m_selectionCornerColumn = -1;
|
||||||
m_selectionSubPage = nullptr;
|
m_selectionSubPage = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,61 +172,114 @@ void TeletextDocument::setFastTextLinkPageNumberOnAllSubPages(int linkNumber, in
|
|||||||
subPage->setFastTextLinkPageNumber(linkNumber, pageNumber);
|
subPage->setFastTextLinkPageNumber(linkNumber, pageNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::cursorUp()
|
void TeletextDocument::cursorUp(bool shiftKey)
|
||||||
{
|
{
|
||||||
|
if (shiftKey && !selectionActive())
|
||||||
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (--m_cursorRow == 0)
|
if (--m_cursorRow == 0)
|
||||||
m_cursorRow = 24;
|
m_cursorRow = 24;
|
||||||
cancelSelection();
|
|
||||||
|
if (shiftKey)
|
||||||
|
emit selectionMoved();
|
||||||
|
else
|
||||||
|
cancelSelection();
|
||||||
|
|
||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::cursorDown()
|
void TeletextDocument::cursorDown(bool shiftKey)
|
||||||
{
|
{
|
||||||
|
if (shiftKey && !selectionActive())
|
||||||
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (++m_cursorRow == 25)
|
if (++m_cursorRow == 25)
|
||||||
m_cursorRow = 1;
|
m_cursorRow = 1;
|
||||||
cancelSelection();
|
|
||||||
|
if (shiftKey)
|
||||||
|
emit selectionMoved();
|
||||||
|
else
|
||||||
|
cancelSelection();
|
||||||
|
|
||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::cursorLeft()
|
void TeletextDocument::cursorLeft(bool shiftKey)
|
||||||
{
|
{
|
||||||
|
if (shiftKey && !selectionActive())
|
||||||
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (--m_cursorColumn == -1) {
|
if (--m_cursorColumn == -1) {
|
||||||
m_cursorColumn = 39;
|
m_cursorColumn = 39;
|
||||||
cursorUp();
|
cursorUp(shiftKey);
|
||||||
}
|
}
|
||||||
cancelSelection();
|
|
||||||
|
if (shiftKey)
|
||||||
|
emit selectionMoved();
|
||||||
|
else
|
||||||
|
cancelSelection();
|
||||||
|
|
||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::cursorRight()
|
void TeletextDocument::cursorRight(bool shiftKey)
|
||||||
{
|
{
|
||||||
|
if (shiftKey && !selectionActive())
|
||||||
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (++m_cursorColumn == 40) {
|
if (++m_cursorColumn == 40) {
|
||||||
m_cursorColumn = 0;
|
m_cursorColumn = 0;
|
||||||
cursorDown();
|
cursorDown(shiftKey);
|
||||||
}
|
}
|
||||||
cancelSelection();
|
|
||||||
|
if (shiftKey)
|
||||||
|
emit selectionMoved();
|
||||||
|
else
|
||||||
|
cancelSelection();
|
||||||
|
|
||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextDocument::moveCursor(int cursorRow, int cursorColumn)
|
void TeletextDocument::moveCursor(int cursorRow, int cursorColumn, bool selectionInProgress)
|
||||||
{
|
{
|
||||||
|
if (selectionInProgress && !selectionActive())
|
||||||
|
setSelectionCorner(m_cursorRow, m_cursorColumn);
|
||||||
|
|
||||||
if (cursorRow != -1)
|
if (cursorRow != -1)
|
||||||
m_cursorRow = cursorRow;
|
m_cursorRow = cursorRow;
|
||||||
if (cursorColumn != -1)
|
if (cursorColumn != -1)
|
||||||
m_cursorColumn = cursorColumn;
|
m_cursorColumn = cursorColumn;
|
||||||
cancelSelection();
|
|
||||||
|
if (selectionInProgress)
|
||||||
|
emit selectionMoved();
|
||||||
|
else
|
||||||
|
cancelSelection();
|
||||||
|
|
||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeletextDocument::setSelectionCorner(int row, int column)
|
||||||
|
{
|
||||||
|
if (m_selectionCornerRow != row || m_selectionCornerColumn != column) {
|
||||||
|
m_selectionSubPage = currentSubPage();
|
||||||
|
m_selectionCornerRow = row;
|
||||||
|
m_selectionCornerColumn = column;
|
||||||
|
|
||||||
|
// emit selectionMoved();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TeletextDocument::setSelection(int topRow, int leftColumn, int bottomRow, int rightColumn)
|
void TeletextDocument::setSelection(int topRow, int leftColumn, int bottomRow, int rightColumn)
|
||||||
{
|
{
|
||||||
if (m_selectionTopRow != topRow || m_selectionBottomRow != bottomRow || m_selectionLeftColumn != leftColumn || m_selectionRightColumn != rightColumn) {
|
if (selectionTopRow() != topRow || selectionBottomRow() != bottomRow || selectionLeftColumn() != leftColumn || selectionRightColumn() != rightColumn) {
|
||||||
m_selectionSubPage = currentSubPage();
|
m_selectionSubPage = currentSubPage();
|
||||||
m_selectionTopRow = topRow;
|
m_selectionCornerRow = topRow;
|
||||||
m_selectionBottomRow = bottomRow;
|
m_cursorRow = bottomRow;
|
||||||
m_selectionLeftColumn = leftColumn;
|
m_selectionCornerColumn = leftColumn;
|
||||||
m_selectionRightColumn = rightColumn;
|
m_cursorColumn = rightColumn;
|
||||||
|
|
||||||
emit selectionMoved();
|
emit selectionMoved();
|
||||||
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +288,7 @@ void TeletextDocument::cancelSelection()
|
|||||||
if (m_selectionSubPage != nullptr) {
|
if (m_selectionSubPage != nullptr) {
|
||||||
m_selectionSubPage = nullptr;
|
m_selectionSubPage = nullptr;
|
||||||
emit selectionMoved();
|
emit selectionMoved();
|
||||||
|
m_selectionCornerRow = m_selectionCornerColumn = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
25
document.h
25
document.h
@@ -64,18 +64,19 @@ public:
|
|||||||
QUndoStack *undoStack() const { return m_undoStack; }
|
QUndoStack *undoStack() const { return m_undoStack; }
|
||||||
int cursorRow() const { return m_cursorRow; }
|
int cursorRow() const { return m_cursorRow; }
|
||||||
int cursorColumn() const { return m_cursorColumn; }
|
int cursorColumn() const { return m_cursorColumn; }
|
||||||
void cursorUp();
|
void cursorUp(bool shiftKey=false);
|
||||||
void cursorDown();
|
void cursorDown(bool shiftKey=false);
|
||||||
void cursorLeft();
|
void cursorLeft(bool shiftKey=false);
|
||||||
void cursorRight();
|
void cursorRight(bool shiftKey=false);
|
||||||
void moveCursor(int, int);
|
void moveCursor(int, int, bool selectionInProgress=false);
|
||||||
int selectionTopRow() const { return m_selectionTopRow; }
|
int selectionTopRow() const { return qMin(m_selectionCornerRow, m_cursorRow); }
|
||||||
int selectionBottomRow() const { return m_selectionBottomRow; }
|
int selectionBottomRow() const { return qMax(m_selectionCornerRow, m_cursorRow); }
|
||||||
int selectionLeftColumn() const { return m_selectionLeftColumn; }
|
int selectionLeftColumn() const { return qMin(m_selectionCornerColumn, m_cursorColumn); }
|
||||||
int selectionRightColumn() const { return m_selectionRightColumn; }
|
int selectionRightColumn() const { return qMax(m_selectionCornerColumn, m_cursorColumn); }
|
||||||
int selectionWidth() const { return m_selectionRightColumn - m_selectionLeftColumn + 1; }
|
int selectionWidth() const { return selectionRightColumn() - selectionLeftColumn() + 1; }
|
||||||
int selectionHeight() const { return m_selectionBottomRow - m_selectionTopRow + 1; }
|
int selectionHeight() const { return selectionBottomRow() - selectionTopRow() + 1; }
|
||||||
bool selectionActive() const { return m_selectionSubPage == currentSubPage(); }
|
bool selectionActive() const { return m_selectionSubPage == currentSubPage(); }
|
||||||
|
void setSelectionCorner(int, int);
|
||||||
void setSelection(int, int, int, int);
|
void setSelection(int, int, int, int);
|
||||||
void cancelSelection();
|
void cancelSelection();
|
||||||
int levelRequired() const;
|
int levelRequired() const;
|
||||||
@@ -99,7 +100,7 @@ private:
|
|||||||
std::vector<LevelOnePage *> m_subPages;
|
std::vector<LevelOnePage *> m_subPages;
|
||||||
std::vector<LevelOnePage *> m_recycleSubPages;
|
std::vector<LevelOnePage *> m_recycleSubPages;
|
||||||
QUndoStack *m_undoStack;
|
QUndoStack *m_undoStack;
|
||||||
int m_cursorRow, m_cursorColumn, m_selectionTopRow, m_selectionBottomRow, m_selectionLeftColumn, m_selectionRightColumn;
|
int m_cursorRow, m_cursorColumn, m_selectionCornerRow, m_selectionCornerColumn;
|
||||||
LevelOnePage *m_selectionSubPage;
|
LevelOnePage *m_selectionSubPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -338,26 +338,27 @@ void TeletextWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
m_teletextDocument->cursorUp();
|
m_teletextDocument->cursorUp(event->modifiers() & Qt::ShiftModifier);
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
m_teletextDocument->cursorDown();
|
m_teletextDocument->cursorDown(event->modifiers() & Qt::ShiftModifier);
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
m_teletextDocument->cursorLeft();
|
m_teletextDocument->cursorLeft(event->modifiers() & Qt::ShiftModifier);
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Right:
|
case Qt::Key_Right:
|
||||||
m_teletextDocument->cursorRight();
|
m_teletextDocument->cursorRight(event->modifiers() & Qt::ShiftModifier);
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
m_teletextDocument->cursorDown();
|
m_teletextDocument->cursorDown();
|
||||||
// fall through
|
|
||||||
case Qt::Key_Home:
|
|
||||||
m_teletextDocument->moveCursor(m_teletextDocument->cursorRow(), 0);
|
m_teletextDocument->moveCursor(m_teletextDocument->cursorRow(), 0);
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_Home:
|
||||||
|
m_teletextDocument->moveCursor(m_teletextDocument->cursorRow(), 0, event->modifiers() & Qt::ShiftModifier);
|
||||||
|
break;
|
||||||
case Qt::Key_End:
|
case Qt::Key_End:
|
||||||
m_teletextDocument->moveCursor(m_teletextDocument->cursorRow(), 39);
|
m_teletextDocument->moveCursor(m_teletextDocument->cursorRow(), 39, event->modifiers() & Qt::ShiftModifier);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_PageUp:
|
case Qt::Key_PageUp:
|
||||||
@@ -416,25 +417,12 @@ void TeletextWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
{
|
{
|
||||||
if (event->buttons() & Qt::LeftButton) {
|
if (event->buttons() & Qt::LeftButton) {
|
||||||
QPair<int, int> position = mouseToRowAndColumn(event->pos());
|
QPair<int, int> position = mouseToRowAndColumn(event->pos());
|
||||||
if (m_selectionInProgress || position.first != m_teletextDocument->cursorRow() || position.second != m_teletextDocument->cursorColumn()) {
|
if (position.first != m_teletextDocument->cursorRow() || position.second != m_teletextDocument->cursorColumn()) {
|
||||||
int topRow, bottomRow, leftColumn, rightColumn;
|
if (!m_selectionInProgress) {
|
||||||
|
m_selectionInProgress = true;
|
||||||
m_selectionInProgress = true;
|
m_teletextDocument->setSelectionCorner(m_teletextDocument->cursorRow(), m_teletextDocument->cursorColumn());
|
||||||
if (m_teletextDocument->cursorRow() < position.first) {
|
|
||||||
topRow = m_teletextDocument->cursorRow();
|
|
||||||
bottomRow = position.first;
|
|
||||||
} else {
|
|
||||||
topRow = position.first;
|
|
||||||
bottomRow = m_teletextDocument->cursorRow();
|
|
||||||
}
|
}
|
||||||
if (m_teletextDocument->cursorColumn() < position.second) {
|
m_teletextDocument->moveCursor(position.first, position.second, true);
|
||||||
leftColumn = m_teletextDocument->cursorColumn();
|
|
||||||
rightColumn = position.second;
|
|
||||||
} else {
|
|
||||||
leftColumn = position.second;
|
|
||||||
rightColumn = m_teletextDocument->cursorColumn();
|
|
||||||
}
|
|
||||||
m_teletextDocument->setSelection(topRow, leftColumn, bottomRow, rightColumn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user