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 PyQt5.Qt import (
|
||||
QApplication, QBuffer, QByteArray, QHBoxLayout, QSize, Qt, QTimer, QUrl, QWidget,
|
||||
pyqtSignal
|
||||
QApplication, QBuffer, QByteArray, QFontDatabase, QHBoxLayout, QSize, Qt, QTimer,
|
||||
QUrl, QWidget, pyqtSignal
|
||||
)
|
||||
from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler
|
||||
from PyQt5.QtWebEngineWidgets import (
|
||||
@ -188,6 +188,35 @@ class ViewerBridge(Bridge):
|
||||
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):
|
||||
|
||||
def __init__(self, parent):
|
||||
@ -195,6 +224,7 @@ class WebPage(QWebEnginePage):
|
||||
QWebEnginePage.__init__(self, profile, parent)
|
||||
profile.setParent(self)
|
||||
secure_webengine(self, for_viewer=True)
|
||||
apply_font_settings(self)
|
||||
self.bridge = ViewerBridge(self)
|
||||
|
||||
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):
|
||||
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):
|
||||
if self.dead_renderer_error_shown:
|
||||
return
|
||||
@ -339,7 +374,7 @@ class WebView(RestartingWebEngineView):
|
||||
return self._page.bridge
|
||||
|
||||
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):
|
||||
getattr(self.bridge, func)(*args)
|
||||
|
||||
@ -369,9 +404,12 @@ class WebView(RestartingWebEngineView):
|
||||
def set_session_data(self, key, val):
|
||||
if key == '*' and val is None:
|
||||
vprefs['session_data'] = {}
|
||||
else:
|
||||
apply_font_settings(self._page)
|
||||
elif key != '*':
|
||||
sd = vprefs['session_data']
|
||||
sd[key] = val
|
||||
if key == 'standalone_font_settings':
|
||||
apply_font_settings(self._page)
|
||||
vprefs['session_data'] = sd
|
||||
|
||||
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
|
||||
# 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 gettext import gettext as _
|
||||
|
||||
from book_list.item_list import build_list, create_item
|
||||
from read_book.prefs.colors import create_colors_panel, commit_colors
|
||||
from read_book.prefs.layout import create_layout_panel, commit_layout
|
||||
from read_book.prefs.user_stylesheet import create_user_stylesheet_panel, commit_user_stylesheet
|
||||
from read_book.prefs.head_foot import create_head_foot_panel, commit_head_foot
|
||||
from dom import clear, ensure_id, svgicon
|
||||
from read_book.globals import runtime
|
||||
from read_book.prefs.colors import commit_colors, create_colors_panel
|
||||
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:
|
||||
@ -59,12 +64,23 @@ class Prefs:
|
||||
document.getElementById(self.title_id).textContent = _('Configure book reader')
|
||||
c = E.div()
|
||||
container.appendChild(c)
|
||||
build_list(c, [
|
||||
items = [
|
||||
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(_('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')),
|
||||
])
|
||||
]
|
||||
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):
|
||||
document.getElementById(self.title_id).textContent = _('Colors')
|
||||
|
@ -40,6 +40,7 @@ defaults = {
|
||||
'header': {},
|
||||
'footer': {'right': 'progress'},
|
||||
'word_actions': v'[]',
|
||||
'standalone_font_settings': {},
|
||||
}
|
||||
|
||||
is_local_setting = {
|
||||
@ -55,6 +56,7 @@ is_local_setting = {
|
||||
'current_color_scheme': True,
|
||||
'base_font_size': True,
|
||||
'controls_help_shown_count': True,
|
||||
'standalone_font_settings': True,
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,8 +175,9 @@ def create_session_data(prefs):
|
||||
|
||||
|
||||
@from_python
|
||||
def create_view(prefs):
|
||||
def create_view(prefs, all_font_families):
|
||||
nonlocal view
|
||||
runtime.all_font_families = all_font_families
|
||||
if view is None:
|
||||
create_session_data(prefs)
|
||||
view = View(document.getElementById('view'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user