mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
vim-mode: support Visual mode with block cursor
This commit is contained in:
parent
00f3665c1c
commit
f429ffe3e5
@ -106,7 +106,8 @@ VVim::VVim(VEditor *p_editor)
|
|||||||
m_leaderKey(Key(Qt::Key_Space)),
|
m_leaderKey(Key(Qt::Key_Space)),
|
||||||
m_replayLeaderSequence(false),
|
m_replayLeaderSequence(false),
|
||||||
m_registerPending(false),
|
m_registerPending(false),
|
||||||
m_insertModeAfterCommand(false)
|
m_insertModeAfterCommand(false),
|
||||||
|
m_positionBeforeVisualMode(0)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_editConfig->m_enableVimMode);
|
Q_ASSERT(m_editConfig->m_enableVimMode);
|
||||||
|
|
||||||
@ -114,8 +115,10 @@ VVim::VVim(VEditor *p_editor)
|
|||||||
|
|
||||||
initRegisters();
|
initRegisters();
|
||||||
|
|
||||||
connect(m_editor->object(), &VEditorObject::selectionChangedByMouse,
|
connect(m_editor->object(), &VEditorObject::mousePressed,
|
||||||
this, &VVim::selectionToVisualMode);
|
this, &VVim::handleMousePressed);
|
||||||
|
connect(m_editor->object(), &VEditorObject::mouseMoved,
|
||||||
|
this, &VVim::handleMouseMoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set @p_cursor's position specified by @p_positionInBlock.
|
// Set @p_cursor's position specified by @p_positionInBlock.
|
||||||
@ -1332,26 +1335,33 @@ bool VVim::handleKeyPressEvent(int key, int modifiers, int *p_autoIndentPos)
|
|||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
{
|
{
|
||||||
// Clear selection and enter normal mode.
|
// Clear selection and enter normal mode.
|
||||||
|
int position = -1;
|
||||||
|
if (checkMode(VimMode::Visual)) {
|
||||||
|
QTextCursor cursor = m_editor->textCursorW();
|
||||||
|
if (cursor.position() > cursor.anchor()) {
|
||||||
|
position = cursor.position() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ret = clearSelection();
|
bool ret = clearSelection();
|
||||||
if (!ret && checkMode(VimMode::Normal)) {
|
if (!ret && checkMode(VimMode::Normal)) {
|
||||||
emit m_editor->object()->requestCloseFindReplaceDialog();
|
emit m_editor->object()->requestCloseFindReplaceDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMode(VimMode::Normal);
|
setMode(VimMode::Normal, true, position);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::Key_V:
|
case Qt::Key_V:
|
||||||
{
|
{
|
||||||
if (modifiers == Qt::NoModifier) {
|
if (modifiers == Qt::NoModifier) {
|
||||||
// Toggle Visual Mode.
|
if (checkMode(VimMode::Visual)) {
|
||||||
clearSelection();
|
setMode(VimMode::Normal, true);
|
||||||
VimMode mode = VimMode::Visual;
|
} else {
|
||||||
if (m_mode == VimMode::Visual) {
|
// Toggle Visual Mode.
|
||||||
mode = VimMode::Normal;
|
setMode(VimMode::Visual);
|
||||||
|
maintainSelectionInVisualMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMode(mode);
|
|
||||||
} else if (modifiers == Qt::ShiftModifier) {
|
} else if (modifiers == Qt::ShiftModifier) {
|
||||||
// Visual Line Mode.
|
// Visual Line Mode.
|
||||||
clearSelection();
|
clearSelection();
|
||||||
@ -2224,9 +2234,18 @@ VimMode VVim::getMode() const
|
|||||||
return m_mode;
|
return m_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VVim::setMode(VimMode p_mode, bool p_clearSelection)
|
void VVim::setMode(VimMode p_mode, bool p_clearSelection, int p_position)
|
||||||
{
|
{
|
||||||
if (m_mode != p_mode) {
|
if (m_mode != p_mode) {
|
||||||
|
QTextCursor cursor = m_editor->textCursorW();
|
||||||
|
int position = p_position;
|
||||||
|
if (position == -1
|
||||||
|
&& m_mode == VimMode::Visual
|
||||||
|
&& p_mode == VimMode::Normal
|
||||||
|
&& cursor.position() > cursor.anchor()) {
|
||||||
|
position = cursor.position() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_clearSelection) {
|
if (p_clearSelection) {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
@ -2240,7 +2259,26 @@ void VVim::setMode(VimMode p_mode, bool p_clearSelection)
|
|||||||
m_mode = p_mode;
|
m_mode = p_mode;
|
||||||
resetState();
|
resetState();
|
||||||
|
|
||||||
m_editor->setCursorBlockEnabled(checkMode(VimMode::Normal));
|
switch (m_mode) {
|
||||||
|
case VimMode::Insert:
|
||||||
|
m_editor->setCursorBlockModeW(CursorBlock::None);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Visual:
|
||||||
|
m_positionBeforeVisualMode = cursor.anchor();
|
||||||
|
V_FALLTHROUGH;
|
||||||
|
|
||||||
|
default:
|
||||||
|
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position != -1) {
|
||||||
|
cursor.setPosition(position);
|
||||||
|
m_editor->setTextCursorW(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
amendCursorPosition();
|
||||||
|
|
||||||
emit modeChanged(m_mode);
|
emit modeChanged(m_mode);
|
||||||
emit vimStatusUpdated(this);
|
emit vimStatusUpdated(this);
|
||||||
@ -2436,8 +2474,10 @@ void VVim::processMoveAction(QList<Token> &p_tokens)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_mode == VimMode::VisualLine) {
|
if (checkMode(VimMode::VisualLine)) {
|
||||||
expandSelectionToWholeLines(cursor);
|
expandSelectionToWholeLines(cursor);
|
||||||
|
} else if (checkMode(VimMode::Visual)) {
|
||||||
|
maintainSelectionInVisualMode(&cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_editor->setTextCursorW(cursor);
|
m_editor->setTextCursorW(cursor);
|
||||||
@ -4848,15 +4888,58 @@ int VVim::blockCountOfPageStep() const
|
|||||||
return pageLineCount;
|
return pageLineCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VVim::selectionToVisualMode(bool p_hasText)
|
void VVim::maintainSelectionInVisualMode(QTextCursor *p_cursor)
|
||||||
{
|
{
|
||||||
if (p_hasText) {
|
// We need to always select the character on current position.
|
||||||
if (m_mode == VimMode::Normal) {
|
QTextCursor *cursor = p_cursor;
|
||||||
// Enter visual mode without clearing the selection.
|
QTextCursor tmpCursor = m_editor->textCursorW();
|
||||||
setMode(VimMode::Visual, false);
|
if (!cursor) {
|
||||||
|
cursor = &tmpCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasChanged = false;
|
||||||
|
int pos = cursor->position();
|
||||||
|
int anchor = cursor->anchor();
|
||||||
|
|
||||||
|
if (pos > anchor) {
|
||||||
|
Q_ASSERT(pos > m_positionBeforeVisualMode);
|
||||||
|
if (anchor > m_positionBeforeVisualMode) {
|
||||||
|
// Re-select.
|
||||||
|
cursor->setPosition(m_positionBeforeVisualMode);
|
||||||
|
cursor->setPosition(pos, QTextCursor::KeepAnchor);
|
||||||
|
hasChanged = true;
|
||||||
}
|
}
|
||||||
} else if (m_mode == VimMode::Visual || m_mode == VimMode::VisualLine) {
|
|
||||||
setMode(VimMode::Normal);
|
m_editor->setCursorBlockModeW(CursorBlock::LeftSide);
|
||||||
|
} else if (pos == anchor) {
|
||||||
|
Q_ASSERT(anchor >= m_positionBeforeVisualMode);
|
||||||
|
// Re-select.
|
||||||
|
if (anchor == m_positionBeforeVisualMode) {
|
||||||
|
cursor->setPosition(m_positionBeforeVisualMode + 1);
|
||||||
|
cursor->setPosition(pos, QTextCursor::KeepAnchor);
|
||||||
|
hasChanged = true;
|
||||||
|
|
||||||
|
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
|
||||||
|
} else {
|
||||||
|
cursor->setPosition(m_positionBeforeVisualMode);
|
||||||
|
cursor->setPosition(pos, QTextCursor::KeepAnchor);
|
||||||
|
hasChanged = true;
|
||||||
|
|
||||||
|
m_editor->setCursorBlockModeW(CursorBlock::LeftSide);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Re-select.
|
||||||
|
if (anchor <= m_positionBeforeVisualMode) {
|
||||||
|
cursor->setPosition(m_positionBeforeVisualMode + 1);
|
||||||
|
cursor->setPosition(pos, QTextCursor::KeepAnchor);
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editor->setCursorBlockModeW(CursorBlock::RightSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasChanged && !p_cursor) {
|
||||||
|
m_editor->setTextCursorW(*cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5828,3 +5911,62 @@ QString VVim::readRegister(int p_key, int p_modifiers)
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VVim::amendCursorPosition()
|
||||||
|
{
|
||||||
|
if (checkMode(VimMode::Normal)) {
|
||||||
|
QTextCursor cursor = m_editor->textCursorW();
|
||||||
|
if (cursor.atBlockEnd() && !cursor.atBlockStart()) {
|
||||||
|
// Normal mode and cursor at the end of a non-empty block.
|
||||||
|
cursor.movePosition(QTextCursor::PreviousCharacter);
|
||||||
|
m_editor->setTextCursorW(cursor);
|
||||||
|
qDebug() << "vvim alter the cursor position one character left";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVim::handleMousePressed(QMouseEvent *p_event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_event);
|
||||||
|
QTextCursor cursor = m_editor->textCursorW();
|
||||||
|
if (checkMode(VimMode::Visual) || checkMode(VimMode::VisualLine)) {
|
||||||
|
setMode(VimMode::Normal);
|
||||||
|
} else if (checkMode(VimMode::Normal)) {
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
setMode(VimMode::Visual, false);
|
||||||
|
maintainSelectionInVisualMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVim::handleMouseMoved(QMouseEvent *p_event)
|
||||||
|
{
|
||||||
|
if (p_event->buttons() != Qt::LeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = m_editor->textCursorW();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
if (checkMode(VimMode::Normal)) {
|
||||||
|
int pos = cursor.position();
|
||||||
|
int anchor = cursor.anchor();
|
||||||
|
QTextBlock block = cursor.document()->findBlock(anchor);
|
||||||
|
if (anchor > 0 && anchor == block.position() + block.length() - 1) {
|
||||||
|
// Move anchor left.
|
||||||
|
cursor.setPosition(anchor - 1);
|
||||||
|
cursor.setPosition(pos, QTextCursor::KeepAnchor);
|
||||||
|
m_editor->setTextCursorW(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
setMode(VimMode::Visual, false);
|
||||||
|
maintainSelectionInVisualMode();
|
||||||
|
} else if (checkMode(VimMode::Visual)) {
|
||||||
|
// We need to assure we always select the character on m_positionBeforeVisualMode.
|
||||||
|
maintainSelectionInVisualMode();
|
||||||
|
}
|
||||||
|
} else if (checkMode(VimMode::Visual)) {
|
||||||
|
// User move cursor in Visual mode. Now the cursor and anchor
|
||||||
|
// are at the same position.
|
||||||
|
maintainSelectionInVisualMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ class VEditor;
|
|||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class VEditConfig;
|
class VEditConfig;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
class QMouseEvent;
|
||||||
|
|
||||||
enum class VimMode {
|
enum class VimMode {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
@ -163,7 +164,7 @@ public:
|
|||||||
VimMode getMode() const;
|
VimMode getMode() const;
|
||||||
|
|
||||||
// Set current mode.
|
// Set current mode.
|
||||||
void setMode(VimMode p_mode, bool p_clearSelection = true);
|
void setMode(VimMode p_mode, bool p_clearSelection = true, int p_position = -1);
|
||||||
|
|
||||||
// Set current register.
|
// Set current register.
|
||||||
void setCurrentRegisterName(QChar p_reg);
|
void setCurrentRegisterName(QChar p_reg);
|
||||||
@ -218,9 +219,13 @@ signals:
|
|||||||
void commandLineTriggered(VVim::CommandLineType p_type);
|
void commandLineTriggered(VVim::CommandLineType p_type);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// When user use mouse to select texts in Normal mode, we should change to
|
void handleMousePressed(QMouseEvent *p_event);
|
||||||
// Visual mode.
|
|
||||||
void selectionToVisualMode(bool p_hasText);
|
void handleMouseMoved(QMouseEvent *p_event);
|
||||||
|
|
||||||
|
// When we display cursor as block, it makes no sense to put cursor at the
|
||||||
|
// end of line.
|
||||||
|
void amendCursorPosition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Struct for a key press.
|
// Struct for a key press.
|
||||||
@ -805,6 +810,12 @@ private:
|
|||||||
Register &getRegister(QChar p_regName) const;
|
Register &getRegister(QChar p_regName) const;
|
||||||
void setRegister(QChar p_regName, const QString &p_val);
|
void setRegister(QChar p_regName, const QString &p_val);
|
||||||
|
|
||||||
|
// May need to do these things:
|
||||||
|
// 1. Change the CursorBlock mode;
|
||||||
|
// 2. Alter the selection to assure the character in m_positionBeforeVisualMode
|
||||||
|
// is always selected.
|
||||||
|
void maintainSelectionInVisualMode(QTextCursor *p_cursor = NULL);
|
||||||
|
|
||||||
VEditor *m_editor;
|
VEditor *m_editor;
|
||||||
const VEditConfig *m_editConfig;
|
const VEditConfig *m_editConfig;
|
||||||
VimMode m_mode;
|
VimMode m_mode;
|
||||||
@ -849,6 +860,11 @@ private:
|
|||||||
// Whether enter insert mode after a command.
|
// Whether enter insert mode after a command.
|
||||||
bool m_insertModeAfterCommand;
|
bool m_insertModeAfterCommand;
|
||||||
|
|
||||||
|
// Cursor position when entering Visual mode.
|
||||||
|
// After displaying cursor as block, we need to always select current character
|
||||||
|
// when entering Visual mode.
|
||||||
|
int m_positionBeforeVisualMode;
|
||||||
|
|
||||||
static const QChar c_unnamedRegister;
|
static const QChar c_unnamedRegister;
|
||||||
static const QChar c_blackHoleRegister;
|
static const QChar c_blackHoleRegister;
|
||||||
static const QChar c_selectionRegister;
|
static const QChar c_selectionRegister;
|
||||||
|
@ -118,4 +118,14 @@ enum class StartupPageType
|
|||||||
Invalid
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cursor block mode.
|
||||||
|
enum class CursorBlock
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
// Display a cursor block on the character on the right side of the cursor.
|
||||||
|
RightSide,
|
||||||
|
// Display a cursor block on the character on the left side of the cursor.
|
||||||
|
LeftSide
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
#include "veditconfig.h"
|
#include "veditconfig.h"
|
||||||
|
#include "vconstants.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
|
|
||||||
class QWidget;
|
class QWidget;
|
||||||
@ -17,6 +18,7 @@ class QTimer;
|
|||||||
class QLabel;
|
class QLabel;
|
||||||
class VVim;
|
class VVim;
|
||||||
enum class VimMode;
|
enum class VimMode;
|
||||||
|
class QMouseEvent;
|
||||||
|
|
||||||
|
|
||||||
enum class SelectionId {
|
enum class SelectionId {
|
||||||
@ -144,9 +146,6 @@ public:
|
|||||||
// @p_modified: if true, delete the whole content and insert the new content.
|
// @p_modified: if true, delete the whole content and insert the new content.
|
||||||
virtual void setContent(const QString &p_content, bool p_modified = false) = 0;
|
virtual void setContent(const QString &p_content, bool p_modified = false) = 0;
|
||||||
|
|
||||||
// Whether display cursor as block.
|
|
||||||
virtual void setCursorBlockEnabled(bool p_enabled) = 0;
|
|
||||||
|
|
||||||
// Set the cursor block's background and foreground.
|
// Set the cursor block's background and foreground.
|
||||||
virtual void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) = 0;
|
virtual void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) = 0;
|
||||||
|
|
||||||
@ -186,6 +185,9 @@ public:
|
|||||||
|
|
||||||
virtual void redoW() = 0;
|
virtual void redoW() = 0;
|
||||||
|
|
||||||
|
// Whether display cursor as block.
|
||||||
|
virtual void setCursorBlockModeW(CursorBlock p_mode) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -332,9 +334,6 @@ signals:
|
|||||||
// Request VEditTab to save this file.
|
// Request VEditTab to save this file.
|
||||||
void saveNote();
|
void saveNote();
|
||||||
|
|
||||||
// Selection changed by mouse.
|
|
||||||
void selectionChangedByMouse(bool p_hasSelection);
|
|
||||||
|
|
||||||
// Emit when Vim status updated.
|
// Emit when Vim status updated.
|
||||||
void vimStatusUpdated(const VVim *p_vim);
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
@ -344,6 +343,10 @@ signals:
|
|||||||
// Request the edit tab to close find and replace dialog.
|
// Request the edit tab to close find and replace dialog.
|
||||||
void requestCloseFindReplaceDialog();
|
void requestCloseFindReplaceDialog();
|
||||||
|
|
||||||
|
void mouseMoved(QMouseEvent *p_event);
|
||||||
|
|
||||||
|
void mousePressed(QMouseEvent *p_event);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Timer for find-wrap label.
|
// Timer for find-wrap label.
|
||||||
void labelTimerTimeout()
|
void labelTimerTimeout()
|
||||||
|
@ -302,7 +302,7 @@ void VMdEditor::mousePressEvent(QMouseEvent *p_event)
|
|||||||
|
|
||||||
VTextEdit::mousePressEvent(p_event);
|
VTextEdit::mousePressEvent(p_event);
|
||||||
|
|
||||||
emit m_object->selectionChangedByMouse(textCursor().hasSelection());
|
emit m_object->mousePressed(p_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event)
|
void VMdEditor::mouseReleaseEvent(QMouseEvent *p_event)
|
||||||
@ -322,7 +322,7 @@ void VMdEditor::mouseMoveEvent(QMouseEvent *p_event)
|
|||||||
|
|
||||||
VTextEdit::mouseMoveEvent(p_event);
|
VTextEdit::mouseMoveEvent(p_event);
|
||||||
|
|
||||||
emit m_object->selectionChangedByMouse(textCursor().hasSelection());
|
emit m_object->mouseMoved(p_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const
|
QVariant VMdEditor::inputMethodQuery(Qt::InputMethodQuery p_query) const
|
||||||
|
@ -59,9 +59,6 @@ public:
|
|||||||
|
|
||||||
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
|
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
// Whether display cursor as block.
|
|
||||||
void setCursorBlockEnabled(bool p_enabled) Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
// Set the cursor block's background and foreground.
|
// Set the cursor block's background and foreground.
|
||||||
void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) Q_DECL_OVERRIDE;
|
void setCursorBlockColor(const QColor &p_bg, const QColor &p_fg) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -148,6 +145,12 @@ public:
|
|||||||
redo();
|
redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whether display cursor as block.
|
||||||
|
void setCursorBlockModeW(CursorBlock p_mode) Q_DECL_OVERRIDE
|
||||||
|
{
|
||||||
|
setCursorBlockMode(p_mode);
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Signal when headers change.
|
// Signal when headers change.
|
||||||
void headersChanged(const QVector<VTableOfContentItem> &p_headers);
|
void headersChanged(const QVector<VTableOfContentItem> &p_headers);
|
||||||
@ -218,11 +221,6 @@ private:
|
|||||||
bool m_freshEdit;
|
bool m_freshEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void VMdEditor::setCursorBlockEnabled(bool p_enabled)
|
|
||||||
{
|
|
||||||
setCursorBlockMode(p_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VMdEditor::setCursorBlockColor(const QColor &p_bg, const QColor &p_fg)
|
inline void VMdEditor::setCursorBlockColor(const QColor &p_bg, const QColor &p_fg)
|
||||||
{
|
{
|
||||||
setCursorBlockBg(p_bg);
|
setCursorBlockBg(p_bg);
|
||||||
|
@ -32,7 +32,7 @@ VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc,
|
|||||||
m_blockImageEnabled(false),
|
m_blockImageEnabled(false),
|
||||||
m_imageWidthConstrainted(false),
|
m_imageWidthConstrainted(false),
|
||||||
m_imageLineColor("#9575CD"),
|
m_imageLineColor("#9575CD"),
|
||||||
m_cursorBlockMode(false),
|
m_cursorBlockMode(CursorBlock::None),
|
||||||
m_virtualCursorBlockWidth(8),
|
m_virtualCursorBlockWidth(8),
|
||||||
m_cursorBlockFg("#EEEEEE"),
|
m_cursorBlockFg("#EEEEEE"),
|
||||||
m_cursorBlockBg("#222222"),
|
m_cursorBlockBg("#222222"),
|
||||||
@ -232,14 +232,17 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
|
|||||||
bool drawCursor = p_context.cursorPosition >= blpos
|
bool drawCursor = p_context.cursorPosition >= blpos
|
||||||
&& p_context.cursorPosition < blpos + bllen;
|
&& p_context.cursorPosition < blpos + bllen;
|
||||||
int cursorWidth = m_cursorWidth;
|
int cursorWidth = m_cursorWidth;
|
||||||
if (drawCursor && m_cursorBlockMode) {
|
int cursorPosition = p_context.cursorPosition - blpos;
|
||||||
if (p_context.cursorPosition == blpos + bllen - 1) {
|
if (drawCursor && m_cursorBlockMode != CursorBlock::None) {
|
||||||
|
if (cursorPosition > 0 && m_cursorBlockMode == CursorBlock::LeftSide) {
|
||||||
|
--cursorPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursorPosition == bllen - 1) {
|
||||||
cursorWidth = m_virtualCursorBlockWidth;
|
cursorWidth = m_virtualCursorBlockWidth;
|
||||||
} else {
|
} else {
|
||||||
// Get the width of the selection to update cursor width.
|
// Get the width of the selection to update cursor width.
|
||||||
cursorWidth = getTextWidthWithinTextLine(layout,
|
cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, 1);
|
||||||
p_context.cursorPosition - blpos,
|
|
||||||
1);
|
|
||||||
if (cursorWidth < m_cursorWidth) {
|
if (cursorWidth < m_cursorWidth) {
|
||||||
cursorWidth = m_cursorWidth;
|
cursorWidth = m_cursorWidth;
|
||||||
}
|
}
|
||||||
@ -263,16 +266,14 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
|
|||||||
if (drawCursor
|
if (drawCursor
|
||||||
|| (p_context.cursorPosition < -1
|
|| (p_context.cursorPosition < -1
|
||||||
&& !layout->preeditAreaText().isEmpty())) {
|
&& !layout->preeditAreaText().isEmpty())) {
|
||||||
int cpos = p_context.cursorPosition;
|
if (p_context.cursorPosition < -1) {
|
||||||
if (cpos < -1) {
|
cursorPosition = layout->preeditAreaPosition()
|
||||||
cpos = layout->preeditAreaPosition() - (cpos + 2);
|
- (p_context.cursorPosition + 2);
|
||||||
} else {
|
|
||||||
cpos -= blpos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layout->drawCursor(p_painter,
|
layout->drawCursor(p_painter,
|
||||||
offset,
|
offset,
|
||||||
cpos,
|
cursorPosition,
|
||||||
cursorWidth);
|
cursorWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,12 +354,6 @@ int VTextDocumentLayout::hitTest(const QPointF &p_point, Qt::HitTestAccuracy p_a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_cursorBlockMode
|
|
||||||
&& off == block.length() - 1
|
|
||||||
&& off != 0) {
|
|
||||||
--off;
|
|
||||||
}
|
|
||||||
|
|
||||||
return block.position() + off;
|
return block.position() + off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include "vconstants.h"
|
||||||
|
|
||||||
class VImageResourceManager2;
|
class VImageResourceManager2;
|
||||||
struct VPreviewedImageInfo;
|
struct VPreviewedImageInfo;
|
||||||
@ -54,7 +55,7 @@ public:
|
|||||||
|
|
||||||
void setImageLineColor(const QColor &p_color);
|
void setImageLineColor(const QColor &p_color);
|
||||||
|
|
||||||
void setCursorBlockMode(bool p_enabled);
|
void setCursorBlockMode(CursorBlock p_mode);
|
||||||
|
|
||||||
void setCursorBlockFg(const QColor &p_color);
|
void setCursorBlockFg(const QColor &p_color);
|
||||||
|
|
||||||
@ -62,6 +63,8 @@ public:
|
|||||||
|
|
||||||
void setVirtualCursorBlockWidth(int p_width);
|
void setVirtualCursorBlockWidth(int p_width);
|
||||||
|
|
||||||
|
void clearLastCursorBlockWidth();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Emit to update current cursor block width if m_cursorBlockMode is enabled.
|
// Emit to update current cursor block width if m_cursorBlockMode is enabled.
|
||||||
void cursorBlockWidthUpdated(int p_width);
|
void cursorBlockWidthUpdated(int p_width);
|
||||||
@ -282,7 +285,7 @@ private:
|
|||||||
QColor m_imageLineColor;
|
QColor m_imageLineColor;
|
||||||
|
|
||||||
// Draw cursor as block.
|
// Draw cursor as block.
|
||||||
bool m_cursorBlockMode;
|
CursorBlock m_cursorBlockMode;
|
||||||
|
|
||||||
// Virtual cursor block: cursor block on no character.
|
// Virtual cursor block: cursor block on no character.
|
||||||
int m_virtualCursorBlockWidth;
|
int m_virtualCursorBlockWidth;
|
||||||
@ -313,9 +316,9 @@ inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_hei
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VTextDocumentLayout::setCursorBlockMode(bool p_enabled)
|
inline void VTextDocumentLayout::setCursorBlockMode(CursorBlock p_mode)
|
||||||
{
|
{
|
||||||
m_cursorBlockMode = p_enabled;
|
m_cursorBlockMode = p_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color)
|
inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color)
|
||||||
@ -332,4 +335,9 @@ inline void VTextDocumentLayout::setVirtualCursorBlockWidth(int p_width)
|
|||||||
{
|
{
|
||||||
m_virtualCursorBlockWidth = p_width;
|
m_virtualCursorBlockWidth = p_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void VTextDocumentLayout::clearLastCursorBlockWidth()
|
||||||
|
{
|
||||||
|
m_lastCursorBlockWidth = -1;
|
||||||
|
}
|
||||||
#endif // VTEXTDOCUMENTLAYOUT_H
|
#endif // VTEXTDOCUMENTLAYOUT_H
|
||||||
|
@ -49,7 +49,7 @@ void VTextEdit::init()
|
|||||||
|
|
||||||
m_blockImageEnabled = false;
|
m_blockImageEnabled = false;
|
||||||
|
|
||||||
m_cursorBlockMode = false;
|
m_cursorBlockMode = CursorBlock::None;
|
||||||
|
|
||||||
m_imageMgr = new VImageResourceManager2();
|
m_imageMgr = new VImageResourceManager2();
|
||||||
|
|
||||||
@ -346,13 +346,14 @@ void VTextEdit::setImageLineColor(const QColor &p_color)
|
|||||||
getLayout()->setImageLineColor(p_color);
|
getLayout()->setImageLineColor(p_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VTextEdit::setCursorBlockMode(bool p_enabled)
|
void VTextEdit::setCursorBlockMode(CursorBlock p_mode)
|
||||||
{
|
{
|
||||||
if (p_enabled != m_cursorBlockMode) {
|
if (p_mode != m_cursorBlockMode) {
|
||||||
m_cursorBlockMode = p_enabled;
|
m_cursorBlockMode = p_mode;
|
||||||
getLayout()->setCursorBlockMode(m_cursorBlockMode);
|
getLayout()->setCursorBlockMode(m_cursorBlockMode);
|
||||||
|
getLayout()->clearLastCursorBlockWidth();
|
||||||
setCursorWidth(m_cursorBlockMode ? VIRTUAL_CURSOR_BLOCK_WIDTH : 1);
|
setCursorWidth(m_cursorBlockMode != CursorBlock::None ? VIRTUAL_CURSOR_BLOCK_WIDTH
|
||||||
|
: 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
|
|
||||||
#include "vlinenumberarea.h"
|
#include "vlinenumberarea.h"
|
||||||
|
#include "vconstants.h"
|
||||||
|
|
||||||
class VTextDocumentLayout;
|
class VTextDocumentLayout;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
@ -56,7 +57,7 @@ public:
|
|||||||
|
|
||||||
void relayout(const QSet<int> &p_blocks);
|
void relayout(const QSet<int> &p_blocks);
|
||||||
|
|
||||||
void setCursorBlockMode(bool p_enabled);
|
void setCursorBlockMode(CursorBlock p_mode);
|
||||||
|
|
||||||
void setCursorBlockFg(const QColor &p_color);
|
void setCursorBlockFg(const QColor &p_color);
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ private:
|
|||||||
|
|
||||||
bool m_blockImageEnabled;
|
bool m_blockImageEnabled;
|
||||||
|
|
||||||
bool m_cursorBlockMode;
|
CursorBlock m_cursorBlockMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void VTextEdit::setLineNumberType(LineNumberType p_type)
|
inline void VTextEdit::setLineNumberType(LineNumberType p_type)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user