Browse Source

VMdEditor: support zoom in/out

Le Tan 8 years ago
parent
commit
1d2183d44e
8 changed files with 195 additions and 11 deletions
  1. 18 0
      src/hgmarkdownhighlighter.h
  2. 1 1
      src/resources/markdown_template.js
  3. 41 0
      src/veditor.cpp
  4. 6 0
      src/veditor.h
  5. 7 6
      src/vedittab.cpp
  6. 101 1
      src/vmdeditor.cpp
  7. 18 0
      src/vmdeditor.h
  8. 3 3
      src/vmdtab.cpp

+ 18 - 0
src/hgmarkdownhighlighter.h

@@ -133,6 +133,10 @@ public:
     // Parse and only update the highlight results for rehighlight().
     void updateHighlightFast();
 
+    QHash<QString, QTextCharFormat> &getCodeBlockStyles();
+
+    QVector<HighlightingStyle> &getHighlightingStyles();
+
 signals:
     void highlightCompleted();
 
@@ -167,8 +171,11 @@ private:
     QTextCharFormat m_colorColumnFormat;
 
     QTextDocument *document;
+
     QVector<HighlightingStyle> highlightingStyles;
+
     QHash<QString, QTextCharFormat> m_codeBlockStyles;
+
     QVector<QVector<HLUnit> > blockHighlights;
 
     // Use another member to store the codeblocks highlights, because the highlight
@@ -294,4 +301,15 @@ inline VTextBlockData *HGMarkdownHighlighter::previousBlockData() const
 
     return static_cast<VTextBlockData *>(block.userData());
 }
+
+inline QHash<QString, QTextCharFormat> &HGMarkdownHighlighter::getCodeBlockStyles()
+{
+    return m_codeBlockStyles;
+}
+
+inline QVector<HighlightingStyle> &HGMarkdownHighlighter::getHighlightingStyles()
+{
+    return highlightingStyles;
+}
+
 #endif

+ 1 - 1
src/resources/markdown_template.js

@@ -199,7 +199,7 @@ document.onkeydown = function(e) {
     case 104:
     case 105:
     {
-        if (pendingKeys.length != 0) {
+        if (pendingKeys.length != 0 || ctrl || shift) {
             accept = false;
             break;
         }

+ 41 - 0
src/veditor.cpp

@@ -878,6 +878,47 @@ bool VEditor::handleMouseMoveEvent(QMouseEvent *p_event)
     return false;
 }
 
+bool VEditor::handleWheelEvent(QWheelEvent *p_event)
+{
+    Qt::KeyboardModifiers modifiers = p_event->modifiers();
+    if (modifiers == Qt::ShiftModifier) {
+        // Scroll horizontally.
+        QPoint numPixels = p_event->pixelDelta();
+        QPoint numDegrees = p_event->angleDelta() / 8;
+
+        QScrollBar *horBar = horizontalScrollBarW();
+        int steps = 0;
+        if (!numPixels.isNull()) {
+            steps = numPixels.y();
+        } else if (!numDegrees.isNull()) {
+            QPoint numSteps = numDegrees / 15;
+            steps = numSteps.y() * horBar->singleStep();
+        }
+
+        if (horBar->minimum() != horBar->maximum()) {
+            horBar->setValue(horBar->value() - steps);
+        }
+
+        p_event->accept();
+        return true;
+    } else if (modifiers == Qt::ControlModifier) {
+        // Zoom in/out.
+        QPoint angle = p_event->angleDelta();
+        if (!angle.isNull() && (angle.y() != 0)) {
+            if (angle.y() > 0) {
+                zoomInW();
+            } else {
+                zoomOutW();
+            }
+        }
+
+        p_event->accept();
+        return true;
+    }
+
+    return false;
+}
+
 void VEditor::requestUpdateVimStatus()
 {
     if (m_editOps) {

+ 6 - 0
src/veditor.h

@@ -186,6 +186,10 @@ public:
     // Whether display cursor as block.
     virtual void setCursorBlockModeW(CursorBlock p_mode) = 0;
 
+    virtual void zoomInW(int p_range = 1) = 0;
+
+    virtual void zoomOutW(int p_range = 1) = 0;
+
 protected:
     void init();
 
@@ -216,6 +220,8 @@ protected:
     bool handleInputMethodQuery(Qt::InputMethodQuery p_query,
                                 QVariant &p_var) const;
 
+    bool handleWheelEvent(QWheelEvent *p_event);
+
     QWidget *m_editor;
 
     VEditorObject *m_object;

+ 7 - 6
src/vedittab.cpp

@@ -68,17 +68,18 @@ void VEditTab::handleFocusChanged(QWidget * /* p_old */, QWidget *p_now)
 
 void VEditTab::wheelEvent(QWheelEvent *p_event)
 {
-    QPoint angle = p_event->angleDelta();
-    Qt::KeyboardModifiers modifiers = p_event->modifiers();
-    if (!angle.isNull() && (angle.y() != 0) && (modifiers & Qt::ControlModifier)) {
-        // Zoom in/out current tab.
-        zoom(angle.y() > 0);
+    if (p_event->modifiers() & Qt::ControlModifier) {
+        QPoint angle = p_event->angleDelta();
+        if (!angle.isNull() && (angle.y() != 0)) {
+            // Zoom in/out current tab.
+            zoom(angle.y() > 0);
+        }
 
         p_event->accept();
         return;
     }
 
-    p_event->ignore();
+    QWidget::wheelEvent(p_event);
 }
 
 VEditTabInfo VEditTab::fetchTabInfo(VEditTabInfo::InfoType p_type) const

+ 101 - 1
src/vmdeditor.cpp

@@ -31,7 +31,8 @@ VMdEditor::VMdEditor(VFile *p_file,
       VEditor(p_file, this),
       m_mdHighlighter(NULL),
       m_freshEdit(true),
-      m_textToHtmlDialog(NULL)
+      m_textToHtmlDialog(NULL),
+      m_zoomDelta(0)
 {
     Q_ASSERT(p_file->getDocType() == DocType::Markdown);
 
@@ -666,6 +667,46 @@ void VMdEditor::clearUnusedImages()
 
 void VMdEditor::keyPressEvent(QKeyEvent *p_event)
 {
+    int modifiers = p_event->modifiers();
+    switch (p_event->key()) {
+    case Qt::Key_Minus:
+    case Qt::Key_Underscore:
+        // Zoom out.
+        if (modifiers & Qt::ControlModifier) {
+            zoomPage(false);
+            return;
+        }
+
+        break;
+
+    case Qt::Key_Plus:
+    case Qt::Key_Equal:
+        // Zoom in.
+        if (modifiers & Qt::ControlModifier) {
+            zoomPage(true);
+            return;
+        }
+
+        break;
+
+    case Qt::Key_0:
+        // Restore zoom.
+        if (modifiers & Qt::ControlModifier) {
+            if (m_zoomDelta > 0) {
+                zoomPage(false, m_zoomDelta);
+            } else if (m_zoomDelta < 0) {
+                zoomPage(true, -m_zoomDelta);
+            }
+
+            return;
+        }
+
+        break;
+
+    default:
+        break;
+    }
+
     if (m_editOps && m_editOps->handleKeyPressEvent(p_event)) {
         return;
     }
@@ -1029,3 +1070,62 @@ void VMdEditor::textToHtmlFinished(const QString &p_text,
         m_textToHtmlDialog->setConvertedHtml(p_baseUrl, p_html);
     }
 }
+
+void VMdEditor::wheelEvent(QWheelEvent *p_event)
+{
+    if (handleWheelEvent(p_event)) {
+        return;
+    }
+
+    VTextEdit::wheelEvent(p_event);
+}
+
+void VMdEditor::zoomPage(bool p_zoomIn, int p_range)
+{
+    int delta;
+    const int minSize = 2;
+
+    if (p_zoomIn) {
+        delta = p_range;
+        zoomIn(p_range);
+    } else {
+        delta = -p_range;
+        zoomOut(p_range);
+    }
+
+    m_zoomDelta += delta;
+
+    QVector<HighlightingStyle> &styles = m_mdHighlighter->getHighlightingStyles();
+    for (auto & it : styles) {
+        int size = it.format.fontPointSize();
+        if (size == 0) {
+            // It contains no font size format.
+            continue;
+        }
+
+        size += delta;
+        if (size < minSize) {
+            size = minSize;
+        }
+
+        it.format.setFontPointSize(size);
+    }
+
+    QHash<QString, QTextCharFormat> &cbStyles = m_mdHighlighter->getCodeBlockStyles();
+    for (auto it = cbStyles.begin(); it != cbStyles.end(); ++it) {
+        int size = it.value().fontPointSize();
+        if (size == 0) {
+            // It contains no font size format.
+            continue;
+        }
+
+        size += delta;
+        if (size < minSize) {
+            size = minSize;
+        }
+
+        it.value().setFontPointSize(size);
+    }
+
+    m_mdHighlighter->rehighlight();
+}

+ 18 - 0
src/vmdeditor.h

@@ -158,6 +158,16 @@ public:
         setCursorBlockMode(p_mode);
     }
 
+    void zoomInW(int p_range = 1) Q_DECL_OVERRIDE
+    {
+        zoomPage(true, p_range);
+    }
+
+    void zoomOutW(int p_range = 1) Q_DECL_OVERRIDE
+    {
+        zoomPage(false, p_range);
+    }
+
 signals:
     // Signal when headers change.
     void headersChanged(const QVector<VTableOfContentItem> &p_headers);
@@ -190,6 +200,8 @@ protected:
 
     void insertFromMimeData(const QMimeData *p_source) Q_DECL_OVERRIDE;
 
+    void wheelEvent(QWheelEvent *p_event) Q_DECL_OVERRIDE;
+
 private slots:
     // Update m_headers according to elements.
     void updateHeaders(const QVector<VElementRegion> &p_headerRegions);
@@ -216,6 +228,10 @@ private:
     // Index in m_headers of current header which contains the cursor.
     int indexOfCurrentHeader() const;
 
+    // Zoom in/out.
+    // We need to maintain the styles font size.
+    void zoomPage(bool p_zoomIn, int p_range = 1);
+
     HGMarkdownHighlighter *m_mdHighlighter;
 
     VCodeBlockHighlightHelper *m_cbHighlighter;
@@ -234,5 +250,7 @@ private:
     bool m_freshEdit;
 
     VCopyTextAsHtmlDialog *m_textToHtmlDialog;
+
+    int m_zoomDelta;
 };
 #endif // VMDEDITOR_H

+ 3 - 3
src/vmdtab.cpp

@@ -677,9 +677,9 @@ void VMdTab::handleWebKeyPressed(int p_key, bool p_ctrl, bool /* p_shift */)
 
 void VMdTab::zoom(bool p_zoomIn, qreal p_step)
 {
-    if (m_isEditMode) {
-        // TODO
-    } else {
+    // Editor will handle it itself.
+    Q_ASSERT(!m_isEditMode);
+    if (!m_isEditMode) {
         zoomWebPage(p_zoomIn, p_step);
     }
 }