bug-fix: vim mode cursor width

This commit is contained in:
Le Tan 2017-12-01 23:24:21 +08:00
parent 87af770612
commit 0d6ed84228
4 changed files with 57 additions and 43 deletions

View File

@ -2240,25 +2240,7 @@ void VVim::setMode(VimMode p_mode, bool p_clearSelection)
m_mode = p_mode; m_mode = p_mode;
resetState(); resetState();
bool cursorBlock = false; m_editor->setCursorBlockEnabled(checkMode(VimMode::Normal));
switch (m_mode) {
case VimMode::Insert:
cursorBlock = true;
m_editor->setCursorBlockColor(g_config->getEditorVimInsertCursorBg(),
g_config->getEditorVimInsertCursorFg());
break;
case VimMode::Normal:
cursorBlock = true;
m_editor->setCursorBlockColor(g_config->getEditorVimNormalCursorBg(),
g_config->getEditorVimNormalCursorFg());
break;
default:
break;
}
m_editor->setCursorBlockEnabled(cursorBlock);
emit modeChanged(m_mode); emit modeChanged(m_mode);
emit vimStatusUpdated(this); emit vimStatusUpdated(this);

View File

@ -35,7 +35,8 @@ VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc,
m_cursorBlockMode(false), m_cursorBlockMode(false),
m_virtualCursorBlockWidth(8), m_virtualCursorBlockWidth(8),
m_cursorBlockFg("#EEEEEE"), m_cursorBlockFg("#EEEEEE"),
m_cursorBlockBg("#222222") m_cursorBlockBg("#222222"),
m_lastCursorBlockWidth(-1)
{ {
} }
@ -230,17 +231,23 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
int bllen = block.length(); int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen; && p_context.cursorPosition < blpos + bllen;
bool drawCursorAsBlock = drawCursor && m_cursorBlockMode; int cursorWidth = m_cursorWidth;
if (drawCursorAsBlock) { if (drawCursor && m_cursorBlockMode) {
if (p_context.cursorPosition == blpos + bllen - 1) { if (p_context.cursorPosition == blpos + bllen - 1) {
drawCursorAsBlock = false; cursorWidth = m_virtualCursorBlockWidth;
} else { } else {
QTextLayout::FormatRange o; // Get the width of the selection to update cursor width.
o.start = p_context.cursorPosition - blpos; cursorWidth = getTextWidthWithinTextLine(layout,
o.length = 1; p_context.cursorPosition - blpos,
o.format.setForeground(m_cursorBlockFg); 1);
o.format.setBackground(m_cursorBlockBg); if (cursorWidth < m_cursorWidth) {
selections.append(o); cursorWidth = m_cursorWidth;
}
}
if (cursorWidth != m_lastCursorBlockWidth) {
m_lastCursorBlockWidth = cursorWidth;
emit cursorBlockWidthUpdated(m_lastCursorBlockWidth);
} }
} }
@ -253,7 +260,7 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
drawMarkers(p_painter, block, offset); drawMarkers(p_painter, block, offset);
if ((drawCursor && !drawCursorAsBlock) if (drawCursor
|| (p_context.cursorPosition < -1 || (p_context.cursorPosition < -1
&& !layout->preeditAreaText().isEmpty())) { && !layout->preeditAreaText().isEmpty())) {
int cpos = p_context.cursorPosition; int cpos = p_context.cursorPosition;
@ -266,8 +273,7 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
layout->drawCursor(p_painter, layout->drawCursor(p_painter,
offset, offset,
cpos, cpos,
m_cursorBlockMode ? m_virtualCursorBlockWidth cursorWidth);
: m_cursorWidth);
} }
offset.ry() += rect.height(); offset.ry() += rect.height();
@ -1074,3 +1080,12 @@ qreal VTextDocumentLayout::fetchInlineImagesForOneLine(const QVector<VPreviewInf
return maxHeight; return maxHeight;
} }
int VTextDocumentLayout::getTextWidthWithinTextLine(const QTextLayout *p_layout,
int p_pos,
int p_length)
{
QTextLine line = p_layout->lineForTextPosition(p_pos);
Q_ASSERT(p_pos + p_length <= line.textStart() + line.textLength());
return line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos);
}

View File

@ -60,6 +60,12 @@ public:
void setCursorBlockBg(const QColor &p_color); void setCursorBlockBg(const QColor &p_color);
void setVirtualCursorBlockWidth(int p_width);
signals:
// Emit to update current cursor block width if m_cursorBlockMode is enabled.
void cursorBlockWidthUpdated(int p_width);
protected: protected:
void documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) Q_DECL_OVERRIDE; void documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) Q_DECL_OVERRIDE;
@ -235,6 +241,10 @@ private:
void scaleSize(QSize &p_size, int p_width, int p_height); void scaleSize(QSize &p_size, int p_width, int p_height);
// Get text length in pixel.
// @p_pos: position within the layout.
int getTextWidthWithinTextLine(const QTextLayout *p_layout, int p_pos, int p_length);
// Document margin on left/right/bottom. // Document margin on left/right/bottom.
qreal m_margin; qreal m_margin;
@ -282,6 +292,8 @@ private:
// Background of cursor block. // Background of cursor block.
QColor m_cursorBlockBg; QColor m_cursorBlockBg;
int m_lastCursorBlockWidth;
}; };
inline qreal VTextDocumentLayout::getLineLeading() const inline qreal VTextDocumentLayout::getLineLeading() const
@ -316,4 +328,8 @@ inline void VTextDocumentLayout::setCursorBlockBg(const QColor &p_color)
m_cursorBlockBg = p_color; m_cursorBlockBg = p_color;
} }
inline void VTextDocumentLayout::setVirtualCursorBlockWidth(int p_width)
{
m_virtualCursorBlockWidth = p_width;
}
#endif // VTEXTDOCUMENTLAYOUT_H #endif // VTEXTDOCUMENTLAYOUT_H

View File

@ -8,6 +8,7 @@
#include "vtextdocumentlayout.h" #include "vtextdocumentlayout.h"
#include "vimageresourcemanager2.h" #include "vimageresourcemanager2.h"
#define VIRTUAL_CURSOR_BLOCK_WIDTH 8
enum class BlockState enum class BlockState
{ {
@ -57,6 +58,16 @@ void VTextEdit::init()
docLayout->setBlockImageEnabled(m_blockImageEnabled); docLayout->setBlockImageEnabled(m_blockImageEnabled);
doc->setDocumentLayout(docLayout); doc->setDocumentLayout(docLayout);
docLayout->setVirtualCursorBlockWidth(VIRTUAL_CURSOR_BLOCK_WIDTH);
connect(docLayout, &VTextDocumentLayout::cursorBlockWidthUpdated,
this, [this](int p_width) {
if (p_width != cursorWidth()
&& p_width > VIRTUAL_CURSOR_BLOCK_WIDTH) {
setCursorWidth(p_width);
}
});
m_lineNumberArea = new VLineNumberArea(this, m_lineNumberArea = new VLineNumberArea(this,
document(), document(),
fontMetrics().width(QLatin1Char('8')), fontMetrics().width(QLatin1Char('8')),
@ -86,10 +97,6 @@ void VTextEdit::resizeEvent(QResizeEvent *p_event)
{ {
QTextEdit::resizeEvent(p_event); QTextEdit::resizeEvent(p_event);
if (m_cursorBlockMode) {
setCursorWidth(p_event->size().width());
}
if (m_lineNumberType != LineNumberType::None) { if (m_lineNumberType != LineNumberType::None) {
QRect rect = contentsRect(); QRect rect = contentsRect();
m_lineNumberArea->setGeometry(QRect(rect.left(), m_lineNumberArea->setGeometry(QRect(rect.left(),
@ -345,13 +352,7 @@ void VTextEdit::setCursorBlockMode(bool p_enabled)
m_cursorBlockMode = p_enabled; m_cursorBlockMode = p_enabled;
getLayout()->setCursorBlockMode(m_cursorBlockMode); getLayout()->setCursorBlockMode(m_cursorBlockMode);
if (p_enabled) { setCursorWidth(m_cursorBlockMode ? VIRTUAL_CURSOR_BLOCK_WIDTH : 1);
// Will set cursor width according to the viewport.
setCursorWidth(viewport()->width());
} else {
// Restore cursor width.
setCursorWidth(1);
}
} }
} }