VTextEdit: support block cursor

This commit is contained in:
Le Tan 2017-11-30 21:25:43 +08:00
parent 72946d0e15
commit b2a435297d
4 changed files with 104 additions and 8 deletions

View File

@ -31,7 +31,11 @@ VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc,
m_imageMgr(p_imageMgr), m_imageMgr(p_imageMgr),
m_blockImageEnabled(false), m_blockImageEnabled(false),
m_imageWidthConstrainted(false), m_imageWidthConstrainted(false),
m_imageLineColor("#9575CD") m_imageLineColor("#9575CD"),
m_cursorBlockMode(false),
m_virtualCursorBlockWidth(8),
m_cursorBlockFg("#EEEEEE"),
m_cursorBlockBg("#222222")
{ {
} }
@ -221,6 +225,25 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
auto selections = formatRangeFromSelection(block, p_context.selections); auto selections = formatRangeFromSelection(block, p_context.selections);
// Draw the cursor.
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
bool drawCursorAsBlock = drawCursor && m_cursorBlockMode;
if (drawCursorAsBlock) {
if (p_context.cursorPosition == blpos + bllen - 1) {
drawCursorAsBlock = false;
} else {
QTextLayout::FormatRange o;
o.start = p_context.cursorPosition - blpos;
o.length = 1;
o.format.setForeground(m_cursorBlockFg);
o.format.setBackground(m_cursorBlockBg);
selections.append(o);
}
}
layout->draw(p_painter, layout->draw(p_painter,
offset, offset,
selections, selections,
@ -230,12 +253,7 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
drawMarkers(p_painter, block, offset); drawMarkers(p_painter, block, offset);
// Draw the cursor. if ((drawCursor && !drawCursorAsBlock)
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
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;
@ -245,7 +263,11 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
cpos -= blpos; cpos -= blpos;
} }
layout->drawCursor(p_painter, offset, cpos, m_cursorWidth); layout->drawCursor(p_painter,
offset,
cpos,
m_cursorBlockMode ? m_virtualCursorBlockWidth
: m_cursorWidth);
} }
offset.ry() += rect.height(); offset.ry() += rect.height();

View File

@ -54,6 +54,12 @@ public:
void setImageLineColor(const QColor &p_color); void setImageLineColor(const QColor &p_color);
void setCursorBlockMode(bool p_enabled);
void setCursorBlockFg(const QColor &p_color);
void setCursorBlockBg(const QColor &p_color);
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;
@ -264,6 +270,18 @@ private:
// Color of the image line. // Color of the image line.
QColor m_imageLineColor; QColor m_imageLineColor;
// Draw cursor as block.
bool m_cursorBlockMode;
// Virtual cursor block: cursor block on no character.
int m_virtualCursorBlockWidth;
// Foreground of cursor block.
QColor m_cursorBlockFg;
// Background of cursor block.
QColor m_cursorBlockBg;
}; };
inline qreal VTextDocumentLayout::getLineLeading() const inline qreal VTextDocumentLayout::getLineLeading() const
@ -282,4 +300,20 @@ inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_hei
p_size.scale(p_width, p_height, Qt::KeepAspectRatio); p_size.scale(p_width, p_height, Qt::KeepAspectRatio);
} }
} }
inline void VTextDocumentLayout::setCursorBlockMode(bool p_enabled)
{
m_cursorBlockMode = p_enabled;
}
inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color)
{
m_cursorBlockFg = p_color;
}
inline void VTextDocumentLayout::setCursorBlockBg(const QColor &p_color)
{
m_cursorBlockBg = p_color;
}
#endif // VTEXTDOCUMENTLAYOUT_H #endif // VTEXTDOCUMENTLAYOUT_H

View File

@ -48,6 +48,8 @@ void VTextEdit::init()
m_blockImageEnabled = false; m_blockImageEnabled = false;
m_cursorBlockMode = false;
m_imageMgr = new VImageResourceManager2(); m_imageMgr = new VImageResourceManager2();
QTextDocument *doc = document(); QTextDocument *doc = document();
@ -84,6 +86,10 @@ 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(),
@ -332,3 +338,29 @@ void VTextEdit::setImageLineColor(const QColor &p_color)
{ {
getLayout()->setImageLineColor(p_color); getLayout()->setImageLineColor(p_color);
} }
void VTextEdit::setCursorBlockMode(bool p_enabled)
{
if (p_enabled != m_cursorBlockMode) {
m_cursorBlockMode = p_enabled;
getLayout()->setCursorBlockMode(m_cursorBlockMode);
if (p_enabled) {
// Will set cursor width according to the viewport.
setCursorWidth(viewport()->width());
} else {
// Restore cursor width.
setCursorWidth(1);
}
}
}
void VTextEdit::setCursorBlockFg(const QColor &p_color)
{
getLayout()->setCursorBlockFg(p_color);
}
void VTextEdit::setCursorBlockBg(const QColor &p_color)
{
getLayout()->setCursorBlockBg(p_color);
}

View File

@ -56,6 +56,12 @@ public:
void relayout(const QSet<int> &p_blocks); void relayout(const QSet<int> &p_blocks);
void setCursorBlockMode(bool p_enabled);
void setCursorBlockFg(const QColor &p_color);
void setCursorBlockBg(const QColor &p_color);
protected: protected:
void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE;
@ -78,6 +84,8 @@ private:
VImageResourceManager2 *m_imageMgr; VImageResourceManager2 *m_imageMgr;
bool m_blockImageEnabled; bool m_blockImageEnabled;
bool m_cursorBlockMode;
}; };
inline void VTextEdit::setLineNumberType(LineNumberType p_type) inline void VTextEdit::setLineNumberType(LineNumberType p_type)