Implement draggable rectangle selection
This commit is contained in:
18
document.cpp
18
document.cpp
@@ -38,6 +38,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_selectionSubPage = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TeletextDocument::~TeletextDocument()
|
TeletextDocument::~TeletextDocument()
|
||||||
@@ -285,6 +286,23 @@ void TeletextDocument::moveCursor(int newCursorRow, int newCursorColumn)
|
|||||||
emit cursorMoved();
|
emit cursorMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeletextDocument::setSelection(int topRow, int leftColumn, int bottomRow, int rightColumn)
|
||||||
|
{
|
||||||
|
if (m_selectionTopRow != topRow || m_selectionBottomRow != bottomRow || m_selectionLeftColumn != leftColumn || m_selectionRightColumn != rightColumn) {
|
||||||
|
m_selectionSubPage = currentSubPage();
|
||||||
|
m_selectionTopRow = topRow;
|
||||||
|
m_selectionBottomRow = bottomRow;
|
||||||
|
m_selectionLeftColumn = leftColumn;
|
||||||
|
m_selectionRightColumn = rightColumn;
|
||||||
|
emit selectionMoved();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TeletextDocument::cancelSelection()
|
||||||
|
{
|
||||||
|
m_selectionSubPage = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OverwriteCharacterCommand::OverwriteCharacterCommand(TeletextDocument *teletextDocument, unsigned char newCharacter, QUndoCommand *parent) : QUndoCommand(parent)
|
OverwriteCharacterCommand::OverwriteCharacterCommand(TeletextDocument *teletextDocument, unsigned char newCharacter, QUndoCommand *parent) : QUndoCommand(parent)
|
||||||
{
|
{
|
||||||
|
|||||||
13
document.h
13
document.h
@@ -61,9 +61,19 @@ public:
|
|||||||
void cursorLeft();
|
void cursorLeft();
|
||||||
void cursorRight();
|
void cursorRight();
|
||||||
void moveCursor(int, int);
|
void moveCursor(int, int);
|
||||||
|
int selectionTopRow() const { return m_selectionTopRow; }
|
||||||
|
int selectionBottomRow() const { return m_selectionBottomRow; }
|
||||||
|
int selectionLeftColumn() const { return m_selectionLeftColumn; }
|
||||||
|
int selectionRightColumn() const { return m_selectionRightColumn; }
|
||||||
|
int selectionWidth() const { return m_selectionRightColumn - m_selectionLeftColumn + 1; }
|
||||||
|
int selectionHeight() const { return m_selectionBottomRow - m_selectionTopRow + 1; }
|
||||||
|
bool selectionActive() const { return m_selectionSubPage == currentSubPage(); }
|
||||||
|
void setSelection(int, int, int, int);
|
||||||
|
void cancelSelection();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void cursorMoved();
|
void cursorMoved();
|
||||||
|
void selectionMoved();
|
||||||
void colourChanged(int);
|
void colourChanged(int);
|
||||||
void contentsChange(int);
|
void contentsChange(int);
|
||||||
void aboutToChangeSubPage();
|
void aboutToChangeSubPage();
|
||||||
@@ -77,7 +87,8 @@ private:
|
|||||||
int m_fastTextLink[6];
|
int m_fastTextLink[6];
|
||||||
std::vector<LevelOnePage *> m_subPages;
|
std::vector<LevelOnePage *> m_subPages;
|
||||||
QUndoStack *m_undoStack;
|
QUndoStack *m_undoStack;
|
||||||
int m_cursorRow, m_cursorColumn;
|
int m_cursorRow, m_cursorColumn, m_selectionTopRow, m_selectionBottomRow, m_selectionLeftColumn, m_selectionRightColumn;
|
||||||
|
LevelOnePage *m_selectionSubPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QPair>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -42,6 +43,7 @@ TeletextWidget::TeletextWidget(QFrame *parent) : QFrame(parent)
|
|||||||
m_levelOnePage = m_teletextDocument->currentSubPage();
|
m_levelOnePage = m_teletextDocument->currentSubPage();
|
||||||
m_pageRender.setTeletextPage(m_levelOnePage);
|
m_pageRender.setTeletextPage(m_levelOnePage);
|
||||||
m_insertMode = false;
|
m_insertMode = false;
|
||||||
|
m_selectionInProgress = false;
|
||||||
m_grid = false;
|
m_grid = false;
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
m_flashTiming = m_flashPhase = 0;
|
m_flashTiming = m_flashPhase = 0;
|
||||||
@@ -50,6 +52,7 @@ TeletextWidget::TeletextWidget(QFrame *parent) : QFrame(parent)
|
|||||||
connect(m_teletextDocument, &TeletextDocument::subPageSelected, this, &TeletextWidget::subPageSelected);
|
connect(m_teletextDocument, &TeletextDocument::subPageSelected, this, &TeletextWidget::subPageSelected);
|
||||||
connect(m_teletextDocument, &TeletextDocument::contentsChange, this, &TeletextWidget::refreshRow);
|
connect(m_teletextDocument, &TeletextDocument::contentsChange, this, &TeletextWidget::refreshRow);
|
||||||
connect(m_teletextDocument, &TeletextDocument::refreshNeeded, this, &TeletextWidget::refreshPage);
|
connect(m_teletextDocument, &TeletextDocument::refreshNeeded, this, &TeletextWidget::refreshPage);
|
||||||
|
connect(m_teletextDocument, &TeletextDocument::selectionMoved, this, QOverload<>::of(&TeletextWidget::update));
|
||||||
}
|
}
|
||||||
|
|
||||||
TeletextWidget::~TeletextWidget()
|
TeletextWidget::~TeletextWidget()
|
||||||
@@ -91,6 +94,11 @@ void TeletextWidget::paintEvent(QPaintEvent *event)
|
|||||||
widgetPainter.drawPixmap(480+m_pageRender.leftSidePanelColumns()*12, 0, *m_pageRender.pagePixmap(m_flashPhase), 480, 0, m_pageRender.rightSidePanelColumns()*12, 250);
|
widgetPainter.drawPixmap(480+m_pageRender.leftSidePanelColumns()*12, 0, *m_pageRender.pagePixmap(m_flashPhase), 480, 0, m_pageRender.rightSidePanelColumns()*12, 250);
|
||||||
if (this->hasFocus())
|
if (this->hasFocus())
|
||||||
widgetPainter.fillRect((m_teletextDocument->cursorColumn()+m_pageRender.leftSidePanelColumns())*12, m_teletextDocument->cursorRow()*10, 12, 10, QColor(128, 128, 128, 192));
|
widgetPainter.fillRect((m_teletextDocument->cursorColumn()+m_pageRender.leftSidePanelColumns())*12, m_teletextDocument->cursorRow()*10, 12, 10, QColor(128, 128, 128, 192));
|
||||||
|
if (m_teletextDocument->selectionActive()) {
|
||||||
|
widgetPainter.setPen(QPen(QColor(192, 192, 192, 224), 1, Qt::DashLine));
|
||||||
|
widgetPainter.setBrush(QBrush(QColor(255, 255, 255, 64)));
|
||||||
|
widgetPainter.drawRect((m_teletextDocument->selectionLeftColumn()+m_pageRender.leftSidePanelColumns())*12, m_teletextDocument->selectionTopRow()*10, m_teletextDocument->selectionWidth()*12-1, m_teletextDocument->selectionHeight()*10-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextWidget::updateFlashTimer(int newFlashTimer)
|
void TeletextWidget::updateFlashTimer(int newFlashTimer)
|
||||||
@@ -329,29 +337,64 @@ void TeletextWidget::backspaceEvent()
|
|||||||
m_teletextDocument->undoStack()->push(backspaceCommand);
|
m_teletextDocument->undoStack()->push(backspaceCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextWidget::cursorToMouse(QPoint mousePosition)
|
QPair<int, int> TeletextWidget::mouseToRowAndColumn(const QPoint &mousePosition)
|
||||||
{
|
{
|
||||||
int newCursorRow = mousePosition.y() / 10;
|
int row = mousePosition.y() / 10;
|
||||||
int newCursorColumn = mousePosition.x() / 12 - m_pageRender.leftSidePanelColumns();
|
int column = mousePosition.x() / 12 - m_pageRender.leftSidePanelColumns();
|
||||||
if (newCursorRow < 1)
|
if (row < 1)
|
||||||
newCursorRow = 1;
|
row = 1;
|
||||||
if (newCursorRow > 24)
|
if (row > 24)
|
||||||
newCursorRow = 24;
|
row = 24;
|
||||||
if (newCursorColumn < 0)
|
if (column < 0)
|
||||||
newCursorColumn = 0;
|
column = 0;
|
||||||
if (newCursorColumn > 39)
|
if (column > 39)
|
||||||
newCursorColumn = 39;
|
column = 39;
|
||||||
m_teletextDocument->moveCursor(newCursorRow, newCursorColumn);
|
return qMakePair(row, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextWidget::mousePressEvent(QMouseEvent *event)
|
void TeletextWidget::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
cursorToMouse(event->pos());
|
m_teletextDocument->cancelSelection();
|
||||||
|
QPair<int, int> position = mouseToRowAndColumn(event->pos());
|
||||||
|
m_teletextDocument->moveCursor(position.first, position.second);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeletextWidget::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->buttons() & Qt::LeftButton) {
|
||||||
|
QPair<int, int> position = mouseToRowAndColumn(event->pos());
|
||||||
|
if (m_selectionInProgress || position.first != m_teletextDocument->cursorRow() || position.second != m_teletextDocument->cursorColumn()) {
|
||||||
|
int topRow, bottomRow, leftColumn, rightColumn;
|
||||||
|
|
||||||
|
m_selectionInProgress = true;
|
||||||
|
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) {
|
||||||
|
leftColumn = m_teletextDocument->cursorColumn();
|
||||||
|
rightColumn = position.second;
|
||||||
|
} else {
|
||||||
|
leftColumn = position.second;
|
||||||
|
rightColumn = m_teletextDocument->cursorColumn();
|
||||||
|
}
|
||||||
|
m_teletextDocument->setSelection(topRow, leftColumn, bottomRow, rightColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TeletextWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton)
|
||||||
|
m_selectionInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
void TeletextWidget::focusInEvent(QFocusEvent *event)
|
void TeletextWidget::focusInEvent(QFocusEvent *event)
|
||||||
{
|
{
|
||||||
QFrame::focusInEvent(event);
|
QFrame::focusInEvent(event);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <QBasicTimer>
|
#include <QBasicTimer>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
|
#include <QPair>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -74,6 +75,8 @@ protected:
|
|||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
void focusInEvent(QFocusEvent *event) override;
|
void focusInEvent(QFocusEvent *event) override;
|
||||||
void focusOutEvent(QFocusEvent *event) override;
|
void focusOutEvent(QFocusEvent *event) override;
|
||||||
|
|
||||||
@@ -82,7 +85,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
TeletextDocument* m_teletextDocument;
|
TeletextDocument* m_teletextDocument;
|
||||||
LevelOnePage* m_levelOnePage;
|
LevelOnePage* m_levelOnePage;
|
||||||
bool m_insertMode, m_grid;
|
bool m_insertMode, m_grid, m_selectionInProgress;
|
||||||
QBasicTimer m_flashTimer;
|
QBasicTimer m_flashTimer;
|
||||||
int m_flashTiming, m_flashPhase;
|
int m_flashTiming, m_flashPhase;
|
||||||
|
|
||||||
@@ -90,7 +93,7 @@ private:
|
|||||||
|
|
||||||
void calculateDimensions();
|
void calculateDimensions();
|
||||||
|
|
||||||
void cursorToMouse(QPoint mousePosition);
|
QPair<int, int> mouseToRowAndColumn(const QPoint &);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user