- fix: select by mouse can't correctly set mouse's column position

- fix: dragging out of the editor and back will cause error
This commit is contained in:
Roy Qu 2021-11-26 19:04:04 +08:00
parent f8a8f5df67
commit ed3f320c50
3 changed files with 111 additions and 93 deletions

View File

@ -1,3 +1,7 @@
Version 0.10.2 For Dev-C++ 7 Beta
- fix: select by mouse can't correctly set mouse's column position
- fix: dragging out of the editor and back will cause error
Version 0.10.1 For Dev-C++ 7 Beta Version 0.10.1 For Dev-C++ 7 Beta
- fix: can't correctly expand watch expression that has spaces in it - fix: can't correctly expand watch expression that has spaces in it
- fix: can't correctly display stl containers in watch - fix: can't correctly display stl containers in watch

View File

@ -34,7 +34,6 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
mOrigLines = mLines; mOrigLines = mLines;
//fPlugins := TList.Create; //fPlugins := TList.Create;
mMouseMoved = false; mMouseMoved = false;
mDragging = false;
mUndoing = false; mUndoing = false;
mLines->connect(mLines.get(), &SynEditStringList::changed, this, &SynEdit::onLinesChanged); mLines->connect(mLines.get(), &SynEditStringList::changed, this, &SynEdit::onLinesChanged);
mLines->connect(mLines.get(), &SynEditStringList::changing, this, &SynEdit::onLinesChanging); mLines->connect(mLines.get(), &SynEditStringList::changing, this, &SynEdit::onLinesChanging);
@ -124,7 +123,7 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
| eoHideShowScrollbars ; | eoHideShowScrollbars ;
mScrollTimer = new QTimer(this); mScrollTimer = new QTimer(this);
mScrollTimer->setInterval(100); //mScrollTimer->setInterval(100);
connect(mScrollTimer, &QTimer::timeout,this, &SynEdit::onScrollTimeout); connect(mScrollTimer, &QTimer::timeout,this, &SynEdit::onScrollTimeout);
mScrollHintColor = QColorConstants::Yellow; mScrollHintColor = QColorConstants::Yellow;
@ -667,9 +666,9 @@ DisplayCoord SynEdit::pixelsToNearestRowColumn(int aX, int aY) const
// don't return a partially visible last line // don't return a partially visible last line
if (aY >= mLinesInWindow * mTextHeight) { if (aY >= mLinesInWindow * mTextHeight) {
aY = mLinesInWindow * mTextHeight - 1; aY = mLinesInWindow * mTextHeight - 1;
if (aY < 0)
aY = 0;
} }
if (aY < 0)
aY = 0;
return { return {
std::max(1, (int)(leftChar() + round(f))), std::max(1, (int)(leftChar() + round(f))),
std::max(1, mTopLine + (aY / mTextHeight)) std::max(1, mTopLine + (aY / mTextHeight))
@ -1764,6 +1763,52 @@ void SynEdit::doToggleComment()
doComment(); doComment();
} }
void SynEdit::doMouseScroll(bool isDragging)
{
QPoint iMousePos;
DisplayCoord C;
int X, Y;
iMousePos = QCursor::pos();
iMousePos = mapFromGlobal(iMousePos);
C = pixelsToRowColumn(iMousePos.x(), iMousePos.y());
C.Row = minMax(C.Row, 1, displayLineCount());
if (mScrollDeltaX != 0) {
setLeftChar(leftChar() + mScrollDeltaX);
X = leftChar();
if (mScrollDeltaX > 0) // scrolling right?
X+=charsInWindow();
C.Column = X;
}
if (mScrollDeltaY != 0) {
if (QApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier))
setTopLine(mTopLine + mScrollDeltaY * mLinesInWindow);
else
setTopLine(mTopLine + mScrollDeltaY);
Y = mTopLine;
if (mScrollDeltaY > 0) // scrolling down?
Y+=mLinesInWindow - 1;
C.Row = minMax(Y, 1, displayLineCount());
}
BufferCoord vCaret = displayToBufferPos(C);
if ((caretX() != vCaret.Char) || (caretY() != vCaret.Line)) {
// changes to line / column in one go
incPaintLock();
auto action = finally([this]{
decPaintLock();
});
internalSetCaretXY(vCaret);
// if MouseCapture is True we're changing selection. otherwise we're dragging
if (isDragging) {
setBlockBegin(mDragSelBeginSave);
setBlockEnd(mDragSelEndSave);
} else
setBlockEnd(caretXY());
}
computeScroll(iMousePos.x(), iMousePos.y(),isDragging);
}
void SynEdit::doDeleteLastChar() void SynEdit::doDeleteLastChar()
{ {
if (mReadOnly) if (mReadOnly)
@ -2481,19 +2526,25 @@ void SynEdit::computeCaret(int X, int Y)
setInternalDisplayXY(vCaretNearestPos); setInternalDisplayXY(vCaretNearestPos);
} }
void SynEdit::computeScroll(int X, int Y) void SynEdit::computeScroll(int X, int Y, bool isDragging)
{ {
if (!isDragging) {
Qt::MouseButtons buttons = qApp->mouseButtons();
if (!buttons.testFlag(Qt::LeftButton))
return;
}
QRect iScrollBounds; // relative to the client area QRect iScrollBounds; // relative to the client area
int dispX,dispY = 2; int dispX=2,dispY = 2;
if (mDragging) { if (isDragging) {
dispX = mCharWidth / 2 -1; dispX = mCharWidth / 2 -1;
dispY = mTextHeight/ 2 -1; dispY = mTextHeight/ 2 -1;
} }
int left = mGutterWidth+frameWidth()+dispX;
iScrollBounds = QRect(mGutterWidth+frameWidth()+dispX, int top = frameWidth()+dispY;
frameWidth()+dispY, iScrollBounds = QRect(left,
mCharsInWindow * mCharWidth-2*dispX, top,
mLinesInWindow * mTextHeight-2*dispY); clientWidth()-left-dispX,
clientHeight()-top-dispY);
if (X < iScrollBounds.left()) if (X < iScrollBounds.left())
mScrollDeltaX = (X - iScrollBounds.left()) / mCharWidth - 1; mScrollDeltaX = (X - iScrollBounds.left()) / mCharWidth - 1;
@ -2502,6 +2553,10 @@ void SynEdit::computeScroll(int X, int Y)
else else
mScrollDeltaX = 0; mScrollDeltaX = 0;
if (isDragging && (X<0 || X>clientRect().width())) {
mScrollDeltaX = 0;
}
if (Y < iScrollBounds.top()) if (Y < iScrollBounds.top())
mScrollDeltaY = (Y - iScrollBounds.top()) / mTextHeight - 1; mScrollDeltaY = (Y - iScrollBounds.top()) / mTextHeight - 1;
else if (Y >= iScrollBounds.bottom()) else if (Y >= iScrollBounds.bottom())
@ -2509,8 +2564,17 @@ void SynEdit::computeScroll(int X, int Y)
else else
mScrollDeltaY = 0; mScrollDeltaY = 0;
if (mScrollDeltaX!=0 || mScrollDeltaY!=0) if (isDragging && (Y<0 || Y>clientRect().height())) {
mScrollTimer->start(); mScrollDeltaY = 0;
}
if (mScrollDeltaX!=0 || mScrollDeltaY!=0) {
if (isDragging) {
mScrollTimer->singleShot(100,this,&SynEdit::onDraggingScrollTimeout);
} else {
mScrollTimer->singleShot(100,this,&SynEdit::onScrollTimeout);
}
}
} }
void SynEdit::doBlockIndent() void SynEdit::doBlockIndent()
@ -2844,11 +2908,6 @@ void SynEdit::decPaintLock()
} }
} }
bool SynEdit::mouseCapture()
{
return hasMouseTracking();
}
int SynEdit::clientWidth() int SynEdit::clientWidth()
{ {
return viewport()->size().width(); return viewport()->size().width();
@ -5988,7 +6047,7 @@ void SynEdit::mouseReleaseEvent(QMouseEvent *event)
processGutterClick(event); processGutterClick(event);
} }
mScrollTimer->stop(); //mScrollTimer->stop();
// if ((button = ) and (Shift = [ssRight]) and Assigned(PopupMenu) then // if ((button = ) and (Shift = [ssRight]) and Assigned(PopupMenu) then
// exit; // exit;
//setMouseTracking(false); //setMouseTracking(false);
@ -6011,9 +6070,6 @@ void SynEdit::mouseMoveEvent(QMouseEvent *event)
Qt::MouseButtons buttons = event->buttons(); Qt::MouseButtons buttons = event->buttons();
int X=event->pos().x(); int X=event->pos().x();
int Y=event->pos().y(); int Y=event->pos().y();
// if (!hasMouseTracking())
// return;
if ((mStateFlags.testFlag(SynStateFlag::sfWaitForDragging))) { if ((mStateFlags.testFlag(SynStateFlag::sfWaitForDragging))) {
if ( ( event->pos() - mMouseDownPos).manhattanLength()>=QApplication::startDragDistance()) { if ( ( event->pos() - mMouseDownPos).manhattanLength()>=QApplication::startDragDistance()) {
mStateFlags.setFlag(SynStateFlag::sfWaitForDragging,false); mStateFlags.setFlag(SynStateFlag::sfWaitForDragging,false);
@ -6027,18 +6083,17 @@ void SynEdit::mouseMoveEvent(QMouseEvent *event)
//drag->setPixmap(iconPixmap); //drag->setPixmap(iconPixmap);
//BeginDrag(false); //BeginDrag(false);
} }
// } else if ((buttons == Qt::LeftButton) && (X > mGutterWidth)) {
} else if ((buttons == Qt::LeftButton)) { } else if ((buttons == Qt::LeftButton)) {
// should we begin scrolling? // should we begin scrolling?
computeScroll(X, Y); computeScroll(X, Y,false);
DisplayCoord P = pixelsToNearestRowColumn(X, Y); DisplayCoord P = pixelsToNearestRowColumn(X, Y);
P.Row = minMax(P.Row, 1, displayLineCount()); P.Row = minMax(P.Row, 1, displayLineCount());
if (mScrollDeltaX != 0) if (mScrollDeltaX != 0)
P.Column = displayX(); P.Column = displayX();
if (mScrollDeltaY != 0) if (mScrollDeltaY != 0)
P.Row = displayY(); P.Row = displayY();
internalSetCaretXY(displayToBufferPos(P)); internalSetCaretXY(displayToBufferPos(P));
setBlockEnd(caretXY()); setBlockEnd(caretXY());
} else if (buttons == Qt::NoButton) { } else if (buttons == Qt::NoButton) {
updateMouseCursor(); updateMouseCursor();
} }
@ -6132,7 +6187,6 @@ QVariant SynEdit::inputMethodQuery(Qt::InputMethodQuery property) const
void SynEdit::dragEnterEvent(QDragEnterEvent *event) void SynEdit::dragEnterEvent(QDragEnterEvent *event)
{ {
if (event->mimeData()->hasFormat("text/plain")) { if (event->mimeData()->hasFormat("text/plain")) {
mDragging = true;
event->acceptProposedAction(); event->acceptProposedAction();
mDragCaretSave = caretXY(); mDragCaretSave = caretXY();
mDragSelBeginSave = blockBegin(); mDragSelBeginSave = blockBegin();
@ -6148,21 +6202,26 @@ void SynEdit::dragEnterEvent(QDragEnterEvent *event)
void SynEdit::dropEvent(QDropEvent *event) void SynEdit::dropEvent(QDropEvent *event)
{ {
//mScrollTimer->stop();
mUndoList->BeginBlock(); mUndoList->BeginBlock();
auto action = finally([this] { auto action = finally([this] {
mUndoList->EndBlock(); mUndoList->EndBlock();
}); });
BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(),
event->pos().y()));
int topLine = mTopLine;
int leftChar = mLeftChar;
if (event->proposedAction() == Qt::DropAction::MoveAction) { if (event->proposedAction() == Qt::DropAction::MoveAction) {
setBlockBegin(mDragSelBeginSave); setBlockBegin(mDragSelBeginSave);
setBlockEnd(mDragSelEndSave); setBlockEnd(mDragSelEndSave);
setSelText(""); setSelText("");
} }
BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(), setTopLine(topLine);
event->pos().y())); setLeftChar(leftChar);
setCaretXY(coord); setCaretXY(coord);
setSelText(event->mimeData()->text()); setSelText(event->mimeData()->text());
event->acceptProposedAction(); event->acceptProposedAction();
mDragging = false;
} }
void SynEdit::dragMoveEvent(QDragMoveEvent *event) void SynEdit::dragMoveEvent(QDragMoveEvent *event)
@ -6174,15 +6233,7 @@ void SynEdit::dragMoveEvent(QDragMoveEvent *event)
} }
// should we begin scrolling? // should we begin scrolling?
computeScroll(event->pos().x(), computeScroll(event->pos().x(),
event->pos().y()); event->pos().y(),true);
// DisplayCoord P = pixelsToNearestRowColumn(X, Y);
// P.Row = minMax(P.Row, 1, displayLineCount());
// if (mScrollDeltaX != 0)
// P.Column = displayX();
// if (mScrollDeltaY != 0)
// P.Row = displayY();
// internalSetCaretXY(displayToBufferPos(P));
// setBlockEnd(caretXY());
BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(), BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(),
event->pos().y())); event->pos().y()));
@ -6198,8 +6249,6 @@ void SynEdit::dragLeaveEvent(QDragLeaveEvent *)
// setBlockBegin(mDragSelBeginSave); // setBlockBegin(mDragSelBeginSave);
// setBlockEnd(mDragSelEndSave); // setBlockEnd(mDragSelEndSave);
// showCaret(); // showCaret();
mScrollTimer->stop();
mDragging = false;
} }
int SynEdit::maxScrollHeight() const int SynEdit::maxScrollHeight() const
@ -6575,46 +6624,10 @@ void SynEdit::onGutterChanged()
void SynEdit::onScrollTimeout() void SynEdit::onScrollTimeout()
{ {
QPoint iMousePos; doMouseScroll(false);
DisplayCoord C; }
int X, Y;
void SynEdit::onDraggingScrollTimeout()
iMousePos = QCursor::pos(); {
iMousePos = mapFromGlobal(iMousePos); doMouseScroll(true);
C = pixelsToRowColumn(iMousePos.x(), iMousePos.y());
C.Row = minMax(C.Row, 1, displayLineCount());
if (mScrollDeltaX != 0) {
setLeftChar(leftChar() + mScrollDeltaX);
X = leftChar();
if (mScrollDeltaX > 0) // scrolling right?
X+=charsInWindow();
C.Column = X;
}
if (mScrollDeltaY != 0) {
if (QApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier))
setTopLine(mTopLine + mScrollDeltaY * mLinesInWindow);
else
setTopLine(mTopLine + mScrollDeltaY);
Y = mTopLine;
if (mScrollDeltaY > 0) // scrolling down?
Y+=mLinesInWindow - 1;
C.Row = minMax(Y, 1, displayLineCount());
}
BufferCoord vCaret = displayToBufferPos(C);
if ((caretX() != vCaret.Char) || (caretY() != vCaret.Line)) {
// changes to line / column in one go
incPaintLock();
auto action = finally([this]{
decPaintLock();
});
internalSetCaretXY(vCaret);
// if MouseCapture is True we're changing selection. otherwise we're dragging
if (mDragging) {
setBlockBegin(mDragSelBeginSave);
setBlockEnd(mDragSelEndSave);
} else
setBlockEnd(caretXY());
}
computeScroll(iMousePos.x(), iMousePos.y());
} }

View File

@ -432,11 +432,10 @@ protected:
private: private:
void clearAreaList(SynEditingAreaList areaList); void clearAreaList(SynEditingAreaList areaList);
void computeCaret(int X, int Y); void computeCaret(int X, int Y);
void computeScroll(int X, int Y); void computeScroll(int X, int Y, bool isDragging);
void incPaintLock(); void incPaintLock();
void decPaintLock(); void decPaintLock();
bool mouseCapture();
int clientWidth(); int clientWidth();
int clientHeight(); int clientHeight();
int clientTop(); int clientTop();
@ -562,6 +561,7 @@ private:
void doComment(); void doComment();
void doUncomment(); void doUncomment();
void doToggleComment(); void doToggleComment();
void doMouseScroll(bool isDragging);
private slots: private slots:
@ -575,6 +575,7 @@ private slots:
void onLinesPutted(int index, int count); void onLinesPutted(int index, int count);
void onRedoAdded(); void onRedoAdded();
void onScrollTimeout(); void onScrollTimeout();
void onDraggingScrollTimeout();
void onUndoAdded(); void onUndoAdded();
void onSizeOrFontChanged(bool bFont); void onSizeOrFontChanged(bool bFont);
void onChanged(); void onChanged();