Adds typewriter scroller (always center) in text editor and fullscreen

This commit is contained in:
Olivier Keshavjee 2017-11-29 10:15:18 +01:00
commit 270d5544b8
7 changed files with 78 additions and 10 deletions

View file

@ -74,6 +74,7 @@ textEditor = {
"marginsLR": 0, "marginsLR": 0,
"marginsTB": 20, "marginsTB": 20,
"backgroundTransparent": False, "backgroundTransparent": False,
"alwaysCenter": False,
} }
revisions = { revisions = {
@ -273,6 +274,7 @@ def load(string, fromString=False, protocol=None):
"marginsLR": 0, "marginsLR": 0,
"marginsTB": 20, "marginsTB": 20,
"backgroundTransparent": False, # Added in 0.6.0 "backgroundTransparent": False, # Added in 0.6.0
"alwaysCenter": False, # Added in 0.7.0
} }
for k in added: for k in added:

View file

@ -198,6 +198,8 @@ class settingsWindow(QWidget, Ui_Settings):
self.spnEditorCursorWidth.setEnabled(opt["cursorWidth"] != 1) self.spnEditorCursorWidth.setEnabled(opt["cursorWidth"] != 1)
self.chkEditorNoBlinking.setChecked(opt["cursorNotBlinking"]) self.chkEditorNoBlinking.setChecked(opt["cursorNotBlinking"])
self.chkEditorNoBlinking.stateChanged.connect(self.setApplicationCursorBlinking) self.chkEditorNoBlinking.stateChanged.connect(self.setApplicationCursorBlinking)
self.chkEditorTypeWriterMode.setChecked(opt["alwaysCenter"])
self.chkEditorTypeWriterMode.stateChanged.connect(self.updateEditorSettings)
# Text areas # Text areas
self.chkEditorMaxWidth.setChecked(opt["maxWidth"] != 0) self.chkEditorMaxWidth.setChecked(opt["maxWidth"] != 0)
self.chkEditorMaxWidth.stateChanged.connect(self.updateEditorSettings) self.chkEditorMaxWidth.stateChanged.connect(self.updateEditorSettings)
@ -479,6 +481,7 @@ class settingsWindow(QWidget, Ui_Settings):
1 if not self.chkEditorCursorWidth.isChecked() else \ 1 if not self.chkEditorCursorWidth.isChecked() else \
self.spnEditorCursorWidth.value() self.spnEditorCursorWidth.value()
self.spnEditorCursorWidth.setEnabled(self.chkEditorCursorWidth.isChecked()) self.spnEditorCursorWidth.setEnabled(self.chkEditorCursorWidth.isChecked())
settings.textEditor["alwaysCenter"] = self.chkEditorTypeWriterMode.isChecked()
# Text area # Text area
settings.textEditor["maxWidth"] = \ settings.textEditor["maxWidth"] = \

View file

@ -206,6 +206,7 @@ class fullScreenEditor(QWidget):
# self.lblWC.setPalette(p) # self.lblWC.setPalette(p)
self.update() self.update()
self.editor.centerCursor()
def paintEvent(self, event): def paintEvent(self, event):
if self._background: if self._background:
@ -307,10 +308,21 @@ class myScrollBar(QScrollBar):
self.timer.timeout.connect(lambda: self.parent().hideWidget(self)) self.timer.timeout.connect(lambda: self.parent().hideWidget(self))
self.valueChanged.connect(lambda v: self.timer.start()) self.valueChanged.connect(lambda v: self.timer.start())
self.valueChanged.connect(lambda: self.parent().showWidget(self)) self.valueChanged.connect(lambda: self.parent().showWidget(self))
self.rangeChanged.connect(self.rangeHasChanged)
def setColor(self, color): def setColor(self, color):
self._color = color self._color = color
def rangeHasChanged(self, min, max):
"""
Adds viewport height to scrollbar max so that we can center cursor
on screen.
"""
if settings.textEditor["alwaysCenter"]:
self.blockSignals(True)
self.setMaximum(max + self.parent().height())
self.blockSignals(False)
def paintEvent(self, event): def paintEvent(self, event):
opt = QStyleOptionSlider() opt = QStyleOptionSlider()
self.initStyleOption(opt) self.initStyleOption(opt)

View file

@ -260,7 +260,7 @@ class MarkdownTokenizer(HighlightTokenizer):
else: else:
# Restart tokenizing on the previous line. # Restart tokenizing on the previous line.
self.requestBacktrack() self.requestBacktrack()
False return False
return False return False
@ -450,7 +450,6 @@ class MarkdownTokenizer(HighlightTokenizer):
MS.MarkdownStateBlockquote, MS.MarkdownStateBlockquote,
MS.MarkdownStateNumberedList, MS.MarkdownStateNumberedList,
MS.MarkdownStateBulletPointList,]: MS.MarkdownStateBulletPointList,]:
self.requestBacktrack()
if self.lineBreakRegex.exactMatch(text): if self.lineBreakRegex.exactMatch(text):
token = Token() token = Token()
token.type = MTT.TokenLineBreak token.type = MTT.TokenLineBreak

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'manuskript/ui/settings_ui.ui' # Form implementation generated from reading ui file 'manuskript/ui/settings_ui.ui'
# #
# Created by: PyQt5 UI code generator 5.9 # Created by: PyQt5 UI code generator 5.5.1
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -1291,6 +1291,13 @@ class Ui_Settings(object):
self.chkEditorNoBlinking.setFont(font) self.chkEditorNoBlinking.setFont(font)
self.chkEditorNoBlinking.setObjectName("chkEditorNoBlinking") self.chkEditorNoBlinking.setObjectName("chkEditorNoBlinking")
self.formLayout_10.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.chkEditorNoBlinking) self.formLayout_10.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.chkEditorNoBlinking)
self.chkEditorTypeWriterMode = QtWidgets.QCheckBox(self.groupBox_15)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
self.chkEditorTypeWriterMode.setFont(font)
self.chkEditorTypeWriterMode.setObjectName("chkEditorTypeWriterMode")
self.formLayout_10.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.chkEditorTypeWriterMode)
self.verticalLayout_22.addWidget(self.groupBox_15) self.verticalLayout_22.addWidget(self.groupBox_15)
self.horizontalLayout_4.addLayout(self.verticalLayout_22) self.horizontalLayout_4.addLayout(self.verticalLayout_22)
icon = QtGui.QIcon.fromTheme("view-text") icon = QtGui.QIcon.fromTheme("view-text")
@ -1480,7 +1487,6 @@ class Ui_Settings(object):
self.layoutWidget = QtWidgets.QWidget(self.splitter) self.layoutWidget = QtWidgets.QWidget(self.splitter)
self.layoutWidget.setObjectName("layoutWidget") self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget) self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget)
self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_14.setObjectName("verticalLayout_14") self.verticalLayout_14.setObjectName("verticalLayout_14")
self.cmbThemeEdit = QtWidgets.QComboBox(self.layoutWidget) self.cmbThemeEdit = QtWidgets.QComboBox(self.layoutWidget)
self.cmbThemeEdit.setObjectName("cmbThemeEdit") self.cmbThemeEdit.setObjectName("cmbThemeEdit")
@ -1495,7 +1501,6 @@ class Ui_Settings(object):
self.stackedWidgetPage1_2.setObjectName("stackedWidgetPage1_2") self.stackedWidgetPage1_2.setObjectName("stackedWidgetPage1_2")
self.formLayout_4 = QtWidgets.QFormLayout(self.stackedWidgetPage1_2) self.formLayout_4 = QtWidgets.QFormLayout(self.stackedWidgetPage1_2)
self.formLayout_4.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) self.formLayout_4.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout_4.setContentsMargins(0, 0, 0, 0)
self.formLayout_4.setObjectName("formLayout_4") self.formLayout_4.setObjectName("formLayout_4")
self.label_17 = QtWidgets.QLabel(self.stackedWidgetPage1_2) self.label_17 = QtWidgets.QLabel(self.stackedWidgetPage1_2)
self.label_17.setObjectName("label_17") self.label_17.setObjectName("label_17")
@ -1527,7 +1532,6 @@ class Ui_Settings(object):
self.stackedWidgetPage2_2.setObjectName("stackedWidgetPage2_2") self.stackedWidgetPage2_2.setObjectName("stackedWidgetPage2_2")
self.formLayout_5 = QtWidgets.QFormLayout(self.stackedWidgetPage2_2) self.formLayout_5 = QtWidgets.QFormLayout(self.stackedWidgetPage2_2)
self.formLayout_5.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) self.formLayout_5.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout_5.setContentsMargins(0, 0, 0, 0)
self.formLayout_5.setObjectName("formLayout_5") self.formLayout_5.setObjectName("formLayout_5")
self.label_20 = QtWidgets.QLabel(self.stackedWidgetPage2_2) self.label_20 = QtWidgets.QLabel(self.stackedWidgetPage2_2)
self.label_20.setObjectName("label_20") self.label_20.setObjectName("label_20")
@ -1625,7 +1629,6 @@ class Ui_Settings(object):
self.page_2.setObjectName("page_2") self.page_2.setObjectName("page_2")
self.formLayout_7 = QtWidgets.QFormLayout(self.page_2) self.formLayout_7 = QtWidgets.QFormLayout(self.page_2)
self.formLayout_7.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) self.formLayout_7.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout_7.setContentsMargins(0, 0, 0, 0)
self.formLayout_7.setObjectName("formLayout_7") self.formLayout_7.setObjectName("formLayout_7")
self.label_29 = QtWidgets.QLabel(self.page_2) self.label_29 = QtWidgets.QLabel(self.page_2)
self.label_29.setObjectName("label_29") self.label_29.setObjectName("label_29")
@ -1675,7 +1678,6 @@ class Ui_Settings(object):
self.stackedWidgetPage3_2.setObjectName("stackedWidgetPage3_2") self.stackedWidgetPage3_2.setObjectName("stackedWidgetPage3_2")
self.formLayout_6 = QtWidgets.QFormLayout(self.stackedWidgetPage3_2) self.formLayout_6 = QtWidgets.QFormLayout(self.stackedWidgetPage3_2)
self.formLayout_6.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) self.formLayout_6.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout_6.setContentsMargins(0, 0, 0, 0)
self.formLayout_6.setObjectName("formLayout_6") self.formLayout_6.setObjectName("formLayout_6")
self.label_26 = QtWidgets.QLabel(self.stackedWidgetPage3_2) self.label_26 = QtWidgets.QLabel(self.stackedWidgetPage3_2)
self.label_26.setObjectName("label_26") self.label_26.setObjectName("label_26")
@ -1778,7 +1780,7 @@ class Ui_Settings(object):
self.horizontalLayout_8.addWidget(self.stack) self.horizontalLayout_8.addWidget(self.stack)
self.retranslateUi(Settings) self.retranslateUi(Settings)
self.stack.setCurrentIndex(5) self.stack.setCurrentIndex(2)
self.tabViews.setCurrentIndex(3) self.tabViews.setCurrentIndex(3)
self.themeStack.setCurrentIndex(1) self.themeStack.setCurrentIndex(1)
self.themeEditStack.setCurrentIndex(3) self.themeEditStack.setCurrentIndex(3)
@ -1970,6 +1972,7 @@ class Ui_Settings(object):
self.chkEditorCursorWidth.setText(_translate("Settings", "Use block insertion of")) self.chkEditorCursorWidth.setText(_translate("Settings", "Use block insertion of"))
self.spnEditorCursorWidth.setSuffix(_translate("Settings", " px")) self.spnEditorCursorWidth.setSuffix(_translate("Settings", " px"))
self.chkEditorNoBlinking.setText(_translate("Settings", "Disable blinking")) self.chkEditorNoBlinking.setText(_translate("Settings", "Disable blinking"))
self.chkEditorTypeWriterMode.setText(_translate("Settings", "Typewriter mode"))
self.tabViews.setTabText(self.tabViews.indexOf(self.tab_4), _translate("Settings", "Text editor")) self.tabViews.setTabText(self.tabViews.indexOf(self.tab_4), _translate("Settings", "Text editor"))
self.lblTitleLabels.setText(_translate("Settings", "Labels")) self.lblTitleLabels.setText(_translate("Settings", "Labels"))
self.btnLabelColor.setShortcut(_translate("Settings", "Ctrl+S")) self.btnLabelColor.setShortcut(_translate("Settings", "Ctrl+S"))

View file

@ -54,7 +54,7 @@
<item> <item>
<widget class="QStackedWidget" name="stack"> <widget class="QStackedWidget" name="stack">
<property name="currentIndex"> <property name="currentIndex">
<number>5</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="stackedWidgetPage1"> <widget class="QWidget" name="stackedWidgetPage1">
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
@ -2619,6 +2619,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkEditorTypeWriterMode">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Typewriter mode</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View file

@ -9,6 +9,7 @@ from PyQt5.QtGui import QTextCursor
from manuskript.ui.views.textEditView import textEditView from manuskript.ui.views.textEditView import textEditView
from manuskript.ui.highlighters import MarkdownHighlighter from manuskript.ui.highlighters import MarkdownHighlighter
from manuskript import settings
# from manuskript.ui.editors.textFormat import textFormat # from manuskript.ui.editors.textFormat import textFormat
# from manuskript.ui.editors.MDFunctions import MDFormatSelection # from manuskript.ui.editors.MDFunctions import MDFormatSelection
@ -28,6 +29,10 @@ class MDEditView(textEditView):
# We have to setup things anew, for the highlighter notably # We have to setup things anew, for the highlighter notably
self.setCurrentModelIndex(index) self.setCurrentModelIndex(index)
self.cursorPositionChanged.connect(self.cursorPositionHasChanged)
self.verticalScrollBar().rangeChanged.connect(
self.scrollBarRangeChanged)
# def focusInEvent(self, event): # def focusInEvent(self, event):
# """Finds textFormatter and attach them to that view.""" # """Finds textFormatter and attach them to that view."""
# textEditView.focusInEvent(self, event) # textEditView.focusInEvent(self, event)
@ -42,6 +47,37 @@ class MDEditView(textEditView):
# tF.updateFromIndex(self._index) # tF.updateFromIndex(self._index)
# tF.setTextEdit(self) # tF.setTextEdit(self)
###########################################################################
# TypeWriterScrolling
###########################################################################
def setCurrentModelIndex(self, index):
textEditView.setCurrentModelIndex(self, index)
self.centerCursor()
def cursorPositionHasChanged(self):
self.centerCursor()
def centerCursor(self, force=False):
cursor = self.cursorRect()
scrollbar = self.verticalScrollBar()
viewport = self.viewport().rect()
if (force or settings.textEditor["alwaysCenter"]
or cursor.bottom() >= viewport.bottom()
or cursor.top() <= viewport.top()):
offset = viewport.center() - cursor.center()
scrollbar.setValue(scrollbar.value() - offset.y())
def scrollBarRangeChanged(self, min, max):
"""
Adds viewport height to scrollbar max so that we can center cursor
on screen.
"""
if settings.textEditor["alwaysCenter"]:
self.verticalScrollBar().blockSignals(True)
self.verticalScrollBar().setMaximum(max + self.viewport().height())
self.verticalScrollBar().blockSignals(False)
########################################################################### ###########################################################################
# FORMATTING (#FIXME) # FORMATTING (#FIXME)
########################################################################### ###########################################################################