mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-09-30 09:17:41 +13:00
Adds typewriter scroller (always center) in text editor and fullscreen
This commit is contained in:
commit
270d5544b8
7 changed files with 78 additions and 10 deletions
|
@ -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:
|
||||||
|
|
|
@ -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"] = \
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
Loading…
Reference in a new issue