mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
UI for viewer font settings
This commit is contained in:
parent
6100a4eeee
commit
7914ad4244
@ -9,8 +9,8 @@ import sys
|
|||||||
from itertools import count
|
from itertools import count
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QApplication, QBuffer, QByteArray, QHBoxLayout, QSize, Qt, QTimer, QUrl, QWidget,
|
QApplication, QBuffer, QByteArray, QFontDatabase, QHBoxLayout, QSize, Qt, QTimer,
|
||||||
pyqtSignal
|
QUrl, QWidget, pyqtSignal
|
||||||
)
|
)
|
||||||
from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler
|
from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler
|
||||||
from PyQt5.QtWebEngineWidgets import (
|
from PyQt5.QtWebEngineWidgets import (
|
||||||
@ -188,6 +188,35 @@ class ViewerBridge(Bridge):
|
|||||||
get_current_cfi = to_js()
|
get_current_cfi = to_js()
|
||||||
|
|
||||||
|
|
||||||
|
def apply_font_settings(page_or_view):
|
||||||
|
s = page_or_view.settings()
|
||||||
|
sd = vprefs['session_data']
|
||||||
|
fs = sd.get('standalone_font_settings', {})
|
||||||
|
if fs.get('serif_family'):
|
||||||
|
s.setFontFamily(s.SerifFont, fs.get('serif_family'))
|
||||||
|
else:
|
||||||
|
s.resetFontFamily(s.SerifFont)
|
||||||
|
if fs.get('sans_family'):
|
||||||
|
s.setFontFamily(s.SansSerifFont, fs.get('sans_family'))
|
||||||
|
else:
|
||||||
|
s.resetFontFamily(s.SansSerifFont)
|
||||||
|
if fs.get('mono_family'):
|
||||||
|
s.setFontFamily(s.FixedFont, fs.get('mono_family'))
|
||||||
|
else:
|
||||||
|
s.resetFontFamily(s.SansSerifFont)
|
||||||
|
sf = fs.get('standard_font') or 'serif'
|
||||||
|
sf = getattr(s, {'serif': 'SerifFont', 'sans': 'SansSerifFont', 'mono': 'FixedFont'}[sf])
|
||||||
|
s.setFontFamily(s.StandardFont, s.fontFamily(sf))
|
||||||
|
mfs = fs.get('minimum_font_size')
|
||||||
|
if mfs is None:
|
||||||
|
s.resetFontSize(s.MinimumFontSize)
|
||||||
|
else:
|
||||||
|
s.setFontSize(s.MinimumFontSize, mfs)
|
||||||
|
s.setFontSize(s.DefaultFontSize, sd.get('base_font_size'))
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
class WebPage(QWebEnginePage):
|
class WebPage(QWebEnginePage):
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
@ -195,6 +224,7 @@ class WebPage(QWebEnginePage):
|
|||||||
QWebEnginePage.__init__(self, profile, parent)
|
QWebEnginePage.__init__(self, profile, parent)
|
||||||
profile.setParent(self)
|
profile.setParent(self)
|
||||||
secure_webengine(self, for_viewer=True)
|
secure_webengine(self, for_viewer=True)
|
||||||
|
apply_font_settings(self)
|
||||||
self.bridge = ViewerBridge(self)
|
self.bridge = ViewerBridge(self)
|
||||||
|
|
||||||
def javaScriptConsoleMessage(self, level, msg, linenumber, source_id):
|
def javaScriptConsoleMessage(self, level, msg, linenumber, source_id):
|
||||||
@ -309,6 +339,11 @@ class WebView(RestartingWebEngineView):
|
|||||||
if ans is not None and not sip.isdeleted(ans):
|
if ans is not None and not sip.isdeleted(ans):
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def change_zoom_by(self, steps=1):
|
||||||
|
ss = vprefs['session_data'].get('zoom_step_size') or 20
|
||||||
|
amt = (ss / 100) * steps
|
||||||
|
self._page.setZoomFactor(self._page.zoomFactor() + amt)
|
||||||
|
|
||||||
def render_process_died(self):
|
def render_process_died(self):
|
||||||
if self.dead_renderer_error_shown:
|
if self.dead_renderer_error_shown:
|
||||||
return
|
return
|
||||||
@ -339,7 +374,7 @@ class WebView(RestartingWebEngineView):
|
|||||||
return self._page.bridge
|
return self._page.bridge
|
||||||
|
|
||||||
def on_bridge_ready(self):
|
def on_bridge_ready(self):
|
||||||
self.bridge.create_view(vprefs['session_data'])
|
self.bridge.create_view(vprefs['session_data'], QFontDatabase().families())
|
||||||
for func, args in iteritems(self.pending_bridge_ready_actions):
|
for func, args in iteritems(self.pending_bridge_ready_actions):
|
||||||
getattr(self.bridge, func)(*args)
|
getattr(self.bridge, func)(*args)
|
||||||
|
|
||||||
@ -369,9 +404,12 @@ class WebView(RestartingWebEngineView):
|
|||||||
def set_session_data(self, key, val):
|
def set_session_data(self, key, val):
|
||||||
if key == '*' and val is None:
|
if key == '*' and val is None:
|
||||||
vprefs['session_data'] = {}
|
vprefs['session_data'] = {}
|
||||||
else:
|
apply_font_settings(self._page)
|
||||||
|
elif key != '*':
|
||||||
sd = vprefs['session_data']
|
sd = vprefs['session_data']
|
||||||
sd[key] = val
|
sd[key] = val
|
||||||
|
if key == 'standalone_font_settings':
|
||||||
|
apply_font_settings(self._page)
|
||||||
vprefs['session_data'] = sd
|
vprefs['session_data'] = sd
|
||||||
|
|
||||||
def do_callback(self, func_name, callback):
|
def do_callback(self, func_name, callback):
|
||||||
|
108
src/pyj/read_book/prefs/fonts.pyj
Normal file
108
src/pyj/read_book/prefs/fonts.pyj
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
from __python__ import hash_literals, bound_methods
|
||||||
|
|
||||||
|
from gettext import gettext as _
|
||||||
|
from dom import unique_id
|
||||||
|
from elementmaker import E
|
||||||
|
from book_list.globals import get_session_data
|
||||||
|
from read_book.globals import runtime
|
||||||
|
|
||||||
|
|
||||||
|
CONTAINER = unique_id('standalone-font-settings')
|
||||||
|
DEFAULT_STANDARD_FONT = 'serif'
|
||||||
|
DEFAULT_MINIMUM_FONT_SIZE = 8
|
||||||
|
DEFAULT_ZOOM_STEP_SIZE = 20
|
||||||
|
|
||||||
|
|
||||||
|
def font_select(name, settings):
|
||||||
|
ans = E.select(name=name)
|
||||||
|
ans.appendChild(E.option(_('— Choose a font —'), value=''))
|
||||||
|
current_val = settings[name]
|
||||||
|
if not current_val:
|
||||||
|
ans.lastChild.setAttribute('selected', 'selected')
|
||||||
|
for family in runtime.all_font_families:
|
||||||
|
if family:
|
||||||
|
ans.appendChild(E.option(family))
|
||||||
|
if family is current_val:
|
||||||
|
ans.lastChild.setAttribute('selected', 'selected')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def standard_font(settings):
|
||||||
|
ans = E.select(name='standard_font')
|
||||||
|
ans.appendChild(E.option(_('Serif'), value='serif'))
|
||||||
|
ans.appendChild(E.option(_('Sans-serif'), value='sans'))
|
||||||
|
ans.appendChild(E.option(_('Monospace'), value='mono'))
|
||||||
|
sf = settings.standard_font or DEFAULT_STANDARD_FONT
|
||||||
|
ans.querySelector(f'[value={sf}]').setAttribute('selected', 'selected')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def minimum_font_size(settings):
|
||||||
|
ans = E.input(max='100', min='0', step='1', type='number', name='minimum_font_size')
|
||||||
|
if jstype(settings.minimum_font_size) is 'number':
|
||||||
|
ans.value = settings.minimum_font_size + ''
|
||||||
|
else:
|
||||||
|
ans.value = '' + DEFAULT_MINIMUM_FONT_SIZE
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def zoom_step_size(settings):
|
||||||
|
ans = E.input(max='100', min='1', step='1', type='number', name='zoom_step_size')
|
||||||
|
if jstype(settings.zoom_step_size) is 'number':
|
||||||
|
ans.value = settings.zoom_step_size + ''
|
||||||
|
else:
|
||||||
|
ans.value = '' + DEFAULT_ZOOM_STEP_SIZE
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def get_container():
|
||||||
|
return document.getElementById(CONTAINER)
|
||||||
|
|
||||||
|
|
||||||
|
def create_fonts_panel(container):
|
||||||
|
container.appendChild(E.div(id=CONTAINER, style='margin: 1rem'))
|
||||||
|
container = container.lastChild
|
||||||
|
container.append(E.div(_('Choose fonts to use for un-styled text:'), style='margin-top: 1rem'))
|
||||||
|
sd = get_session_data()
|
||||||
|
settings = sd.get('standalone_font_settings')
|
||||||
|
|
||||||
|
def row(label, widget):
|
||||||
|
return E.tr(E.td(label + ':\xa0', style='padding-top: 1ex'), E.td(widget, style='padding-top: 1ex'))
|
||||||
|
|
||||||
|
container.append(E.table(style='margin-top: 1rem',
|
||||||
|
row(_('Serif family'), font_select('serif_family', settings)),
|
||||||
|
row(_('Sans-serif family'), font_select('sans_family', settings)),
|
||||||
|
row(_('Monospace family'), font_select('mono_family', settings)),
|
||||||
|
row(_('Standard font'), standard_font(settings)),
|
||||||
|
))
|
||||||
|
|
||||||
|
container.append(E.div(_('Zoom related settings'), style='margin-top: 1rem'))
|
||||||
|
container.append(E.table(style='margin-top: 1rem',
|
||||||
|
row(_('Zoom step size (%s)'), zoom_step_size(settings)),
|
||||||
|
row(_('Minimum font size (px)'), minimum_font_size(settings)),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
develop = create_fonts_panel
|
||||||
|
|
||||||
|
|
||||||
|
def commit_fonts(onchange):
|
||||||
|
sd = get_session_data()
|
||||||
|
container = get_container()
|
||||||
|
vals = {}
|
||||||
|
zss = parseInt(container.querySelector('[name=zoom_step_size]').value)
|
||||||
|
if zss is not DEFAULT_ZOOM_STEP_SIZE:
|
||||||
|
vals.zoom_step_size = zss
|
||||||
|
mfs = parseInt(container.querySelector('[name=minimum_font_size]').value)
|
||||||
|
if mfs is not DEFAULT_MINIMUM_FONT_SIZE:
|
||||||
|
vals.minimum_font_size = mfs
|
||||||
|
sf = container.querySelector('[name=standard_font]').value
|
||||||
|
if sf is not DEFAULT_STANDARD_FONT:
|
||||||
|
vals.standard_font = sf
|
||||||
|
for q in ('serif_family', 'sans_family', 'mono_family'):
|
||||||
|
val = container.querySelector(f'[name={q}]').value
|
||||||
|
if val:
|
||||||
|
vals[q] = val
|
||||||
|
sd.set('standalone_font_settings', vals)
|
@ -1,15 +1,20 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
from __python__ import hash_literals, bound_methods
|
from __python__ import bound_methods, hash_literals
|
||||||
|
|
||||||
from gettext import gettext as _
|
|
||||||
from dom import svgicon, ensure_id, clear
|
|
||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
from book_list.item_list import build_list, create_item
|
from book_list.item_list import build_list, create_item
|
||||||
from read_book.prefs.colors import create_colors_panel, commit_colors
|
from dom import clear, ensure_id, svgicon
|
||||||
from read_book.prefs.layout import create_layout_panel, commit_layout
|
from read_book.globals import runtime
|
||||||
from read_book.prefs.user_stylesheet import create_user_stylesheet_panel, commit_user_stylesheet
|
from read_book.prefs.colors import commit_colors, create_colors_panel
|
||||||
from read_book.prefs.head_foot import create_head_foot_panel, commit_head_foot
|
from read_book.prefs.fonts import commit_fonts, create_fonts_panel
|
||||||
|
from read_book.prefs.head_foot import commit_head_foot, create_head_foot_panel
|
||||||
|
from read_book.prefs.layout import commit_layout, create_layout_panel
|
||||||
|
from read_book.prefs.user_stylesheet import (
|
||||||
|
commit_user_stylesheet, create_user_stylesheet_panel
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Prefs:
|
class Prefs:
|
||||||
@ -59,12 +64,23 @@ class Prefs:
|
|||||||
document.getElementById(self.title_id).textContent = _('Configure book reader')
|
document.getElementById(self.title_id).textContent = _('Configure book reader')
|
||||||
c = E.div()
|
c = E.div()
|
||||||
container.appendChild(c)
|
container.appendChild(c)
|
||||||
build_list(c, [
|
items = [
|
||||||
create_item(_('Colors'), def():self.show_panel('colors');, _('Colors of the page and text')),
|
create_item(_('Colors'), def():self.show_panel('colors');, _('Colors of the page and text')),
|
||||||
create_item(_('Page layout'), def():self.show_panel('layout');, _('Page margins and number of pages per screen')),
|
create_item(_('Page layout'), def():self.show_panel('layout');, _('Page margins and number of pages per screen')),
|
||||||
create_item(_('User style sheet'), def():self.show_panel('user_stylesheet');, _('Style rules for text')),
|
create_item(_('User style sheet'), def():self.show_panel('user_stylesheet');, _('Style rules for text')),
|
||||||
create_item(_('Headers and footers'), def():self.show_panel('head_foot');, _('Customize the headers and footers')),
|
create_item(_('Headers and footers'), def():self.show_panel('head_foot');, _('Customize the headers and footers')),
|
||||||
])
|
]
|
||||||
|
if runtime.is_standalone_viewer:
|
||||||
|
items.push(create_item(
|
||||||
|
_('Fonts'), def():self.show_panel('fonts');, _('Font choices')))
|
||||||
|
build_list(c, items)
|
||||||
|
|
||||||
|
def display_fonts(self, container):
|
||||||
|
document.getElementById(self.title_id).textContent = _('Fonts')
|
||||||
|
create_fonts_panel(container)
|
||||||
|
|
||||||
|
def close_fonts(self):
|
||||||
|
commit_fonts(self.onchange, self.container)
|
||||||
|
|
||||||
def display_colors(self, container):
|
def display_colors(self, container):
|
||||||
document.getElementById(self.title_id).textContent = _('Colors')
|
document.getElementById(self.title_id).textContent = _('Colors')
|
||||||
|
@ -40,6 +40,7 @@ defaults = {
|
|||||||
'header': {},
|
'header': {},
|
||||||
'footer': {'right': 'progress'},
|
'footer': {'right': 'progress'},
|
||||||
'word_actions': v'[]',
|
'word_actions': v'[]',
|
||||||
|
'standalone_font_settings': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
is_local_setting = {
|
is_local_setting = {
|
||||||
@ -55,6 +56,7 @@ is_local_setting = {
|
|||||||
'current_color_scheme': True,
|
'current_color_scheme': True,
|
||||||
'base_font_size': True,
|
'base_font_size': True,
|
||||||
'controls_help_shown_count': True,
|
'controls_help_shown_count': True,
|
||||||
|
'standalone_font_settings': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,8 +175,9 @@ def create_session_data(prefs):
|
|||||||
|
|
||||||
|
|
||||||
@from_python
|
@from_python
|
||||||
def create_view(prefs):
|
def create_view(prefs, all_font_families):
|
||||||
nonlocal view
|
nonlocal view
|
||||||
|
runtime.all_font_families = all_font_families
|
||||||
if view is None:
|
if view is None:
|
||||||
create_session_data(prefs)
|
create_session_data(prefs)
|
||||||
view = View(document.getElementById('view'))
|
view = View(document.getElementById('view'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user