Refactor the viewer preferences

DRYer and add restore default/OK/Cancel buttons to all preferences
sections
This commit is contained in:
Kovid Goyal 2019-10-07 22:23:40 +05:30
parent a2708e8ea2
commit 3c1c90ba7d
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
9 changed files with 131 additions and 63 deletions

View File

@ -1,15 +1,16 @@
# 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, set_css, add_extra_css, build_rule, clear, unique_id
from elementmaker import E
from book_list.globals import get_session_data
from read_book.globals import default_color_schemes, ui_operations
from modals import error_dialog
from widgets import create_button
from gettext import gettext as _
from book_list.globals import get_session_data
from dom import add_extra_css, build_rule, clear, set_css, svgicon, unique_id
from modals import error_dialog
from read_book.globals import default_color_schemes, ui_operations
from read_book.prefs.utils import create_button_box
from widgets import create_button
CONTAINER = unique_id('reader-color-scheme')
COLOR_LIST = unique_id()
@ -173,7 +174,7 @@ def set_action_button_visibility():
else:
button.style.display = 'inline-block' if is_custom else 'none'
def create_colors_panel(container):
def create_colors_panel(container, apply_func, cancel_func):
container.appendChild(E.div(id=CONTAINER))
container = container.lastChild
cs = resolve_color_scheme()
@ -207,9 +208,10 @@ def create_colors_panel(container):
)),
),
E.div(style="display:flex; justify-content: flex-end; margin: 1ex 1em",
create_button(_('OK'), 'check', add_color_scheme), E.span('\xa0'), create_button(_('Cancel'), 'close', add_color_scheme.bind('cancel'))
create_button(_('Apply'), 'check', add_color_scheme), E.span('\xa0'), create_button(_('Discard'), 'close', add_color_scheme.bind('cancel'))
)))
set_action_button_visibility()
container.appendChild(E.div(style='margin: 1rem', create_button_box(None, apply_func, cancel_func)))
develop = create_colors_panel
@ -221,3 +223,4 @@ def commit_colors(onchange):
sd = get_session_data()
sd.set('current_color_scheme', ccs)
ui_operations.update_color_scheme()
onchange()

View File

@ -8,7 +8,7 @@ from gettext import gettext as _
from book_list.globals import get_session_data
from dom import unique_id
from read_book.globals import runtime
from widgets import create_button
from read_book.prefs.utils import create_button_box
CONTAINER = unique_id('standalone-font-settings')
DEFAULT_STANDARD_FONT = 'serif'
@ -71,7 +71,7 @@ def get_container():
return document.getElementById(CONTAINER)
def create_fonts_panel(container):
def create_fonts_panel(container, apply_func, cancel_func):
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'))
@ -94,9 +94,7 @@ def create_fonts_panel(container):
row(_('Minimum font size (px)'), minimum_font_size(settings)),
))
container.appendChild(E.div(
style='margin-top: 1rem', create_button(_('Restore defaults'), action=restore_defaults)
))
container.appendChild(create_button_box(restore_defaults, apply_func, cancel_func))
develop = create_fonts_panel

View File

@ -7,7 +7,8 @@ from gettext import gettext as _, ngettext
from book_list.globals import get_session_data
from dom import unique_id
from session import get_interface_data
from read_book.prefs.utils import create_button_box
from session import defaults, get_interface_data
from utils import fmt_sidx
CONTAINER = unique_id('reader-hf-prefs')
@ -76,7 +77,14 @@ def get_setting(table):
return ans
def create_head_foot_panel(container):
def restore_defaults():
container = document.getElementById(CONTAINER)
for which in 'header footer'.split(' '):
table = container.querySelector(f'table[data-which={which}]')
apply_setting(table, defaults[which] or {})
def create_head_foot_panel(container, apply_func, cancel_func):
container.appendChild(E.div(id=CONTAINER))
container = container.lastChild
container.appendChild(E.h4(_('Header'), style="margin: 1rem"))
@ -89,6 +97,7 @@ def create_head_foot_panel(container):
for which in 'header footer'.split(' '):
table = container.querySelector(f'table[data-which={which}]')
apply_setting(table, sd.get(which) or {})
container.appendChild(E.div(style='margin: 1rem', create_button_box(restore_defaults, apply_func, cancel_func)))
def commit_head_foot(onchange, container):

View File

@ -1,11 +1,14 @@
# 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 add_extra_css, build_rule, unique_id, element
from book_list.globals import get_session_data
from elementmaker import E
from gettext import gettext as _
from book_list.globals import get_session_data
from dom import add_extra_css, build_rule, element, unique_id
from read_book.prefs.utils import create_button_box
from session import defaults
CONTAINER = unique_id('reader-page-layout')
MARGINS = unique_id('reader-page-margins')
@ -20,7 +23,20 @@ add_extra_css(def():
return style
)
def create_layout_panel(container):
def restore_defaults():
container = document.getElementById(CONTAINER)
for which in 'top bottom left right'.split(' '):
container.querySelector('input[name={}]'.format(which)).value = str(defaults['margin_' + which])
for name in 'paged flow'.split(' '):
container.querySelector('input[data-name={}]'.format(name)).checked = defaults.read_mode is name
for name in 'portrait landscape'.split(' '):
container.querySelector('input[name={}]'.format(name)).value = str(defaults.columns_per_screen[name])
for which in 'width height'.split(' '):
container.querySelector('input[name={}]'.format(which)).value = str(defaults['max_text_' + which])
container.querySelector('input[name=cover_preserve_aspect_ratio]').checked = defaults.cover_preserve_aspect_ratio
def create_layout_panel(container, apply_func, cancel_func):
container.appendChild(E.div(id=CONTAINER))
container = container.lastChild
sd = get_session_data()
@ -42,7 +58,7 @@ def create_layout_panel(container):
rm = 'flow' if rm is 'flow' else 'paged'
def rb(name, text):
d = container.lastChild
d.appendChild(E.label(E.input(type='radio', name='page-layout-mode', checked=rm is name), text))
d.appendChild(E.label(E.input(type='radio', name='page-layout-mode', data_name=name, checked=rm is name), text))
rb('paged', _('Paged mode'))
container.lastChild.appendChild(E.span('\xa0', style='width:3em'))
rb('flow', _('Flow mode'))
@ -64,6 +80,7 @@ def create_layout_panel(container):
sec(_('Control how the cover is displayed'))
container.appendChild(E.div(style='margin: 1ex 2rem; display: flex;',
E.label(E.input(type='checkbox', name='cover_preserve_aspect_ratio', checked=sd.get('cover_preserve_aspect_ratio')), _('Preserve cover aspect ratio'))))
container.appendChild(E.div(style='margin: 1rem', create_button_box(restore_defaults, apply_func, cancel_func)))
develop = create_layout_panel

View File

@ -40,6 +40,11 @@ class Prefs:
def onchange(self):
self.on_change()
def cancel(self):
if self.stack.length > 1:
self.stack.pop()
self.display_panel(self.stack[-1])
def onclose(self):
if self.stack.length > 1:
which = self.stack.pop()
@ -50,6 +55,10 @@ class Prefs:
else:
self.close_func()
def create_panel(self, container, which, create_func):
document.getElementById(self.title_id).textContent = self.title_map[which] or which
create_func(container, self.onclose, self.cancel)
@property
def container(self):
return document.getElementById(self.container_id)
@ -67,73 +76,68 @@ class Prefs:
document.getElementById(self.title_id).textContent = _('Configure book reader')
c = E.div()
container.appendChild(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(_('Styles'), def():self.show_panel('user_stylesheet');, _('Style rules for text and background image')),
create_item(_('Headers and footers'), def():self.show_panel('head_foot');, _('Customize the headers and footers')),
create_item(_('Scrolling behavior'), def():self.show_panel('scrolling');, _('Control how the viewer scrolls')),
create_item(_('Keyboard shortcuts'), def():self.show_panel('keyboard');, _('Customize the keyboard shortcuts')),
]
self.title_map = {}
items = []
def ci(title, which, subtitle):
items.push(create_item(title, self.show_panel.bind(None, which), subtitle))
self.title_map[which] = title
ci(_('Colors'), 'colors', _('Colors of the page and text'))
ci(_('Page layout'), 'layout', _('Page margins and number of pages per screen'))
ci(_('Styles'), 'user_stylesheet', _('Style rules for text and background image'))
ci(_('Headers and footers'), 'head_foot', _('Customize the headers and footers'))
ci(_('Scrolling behavior'), 'scrolling', _('Control how the viewer scrolls'))
ci(_('Keyboard shortcuts'), 'keyboard', _('Customize the keyboard shortcuts'))
if runtime.is_standalone_viewer:
items.push(create_item(
_('Fonts'), def():self.show_panel('fonts');, _('Font choices')))
items.push(create_item(
_('Miscellaneous'), def():self.show_panel('misc');, _('Window size, last read position, etc.')))
ci(_('Fonts'), 'fonts', _('Font choices'))
ci(_('Miscellaneous'), 'misc', _('Window size, last read position, etc.'))
build_list(c, items)
def display_fonts(self, container):
document.getElementById(self.title_id).textContent = _('Fonts')
create_fonts_panel(container)
self.create_panel(container, 'fonts', create_fonts_panel)
def close_fonts(self):
commit_fonts(self.onchange, self.container)
def display_misc(self, container):
document.getElementById(self.title_id).textContent = _('Miscellaneous')
create_misc_panel(container)
self.create_panel(container, 'misc', create_misc_panel)
def close_misc(self):
commit_misc(self.onchange, self.container)
def display_colors(self, container):
document.getElementById(self.title_id).textContent = _('Colors')
create_colors_panel(container)
self.create_panel(container, 'colors', create_colors_panel)
def close_colors(self):
commit_colors(self.onchange, self.container)
def display_layout(self, container):
document.getElementById(self.title_id).textContent = _('Page layout')
create_layout_panel(container)
self.create_panel(container, 'layout', create_layout_panel)
def close_layout(self):
commit_layout(self.onchange, self.container)
def display_user_stylesheet(self, container):
document.getElementById(self.title_id).textContent = _('Styles')
create_user_stylesheet_panel(container)
self.create_panel(container, 'user_stylesheet', create_user_stylesheet_panel)
def close_user_stylesheet(self):
commit_user_stylesheet(self.onchange, self.container)
def display_head_foot(self, container):
document.getElementById(self.title_id).textContent = _('Headers and footers')
create_head_foot_panel(container)
self.create_panel(container, 'head_foot', create_head_foot_panel)
def close_head_foot(self):
commit_head_foot(self.onchange, self.container)
def display_keyboard(self, container):
document.getElementById(self.title_id).textContent = _('Keyboard shortcuts')
create_keyboard_panel(container, self.onclose, self.onchange)
self.create_panel(container, 'keyboard', create_keyboard_panel)
def close_keyboard(self):
commit_keyboard(self.onchange, self.container)
def display_scrolling(self, container):
document.getElementById(self.title_id).textContent = _('Scrolling behavior')
create_scrolling_panel(container, self.onclose)
self.create_panel(container, 'scrolling', create_scrolling_panel)
def close_scrolling(self):
commit_scrolling(self.onchange, self.container)

View File

@ -7,8 +7,9 @@ from gettext import gettext as _
from book_list.globals import get_session_data
from dom import unique_id
from widgets import create_button
from session import defaults
from read_book.prefs.utils import create_button_box
CONTAINER = unique_id('standalone-misc-settings')
DEFAULTS = {
@ -30,7 +31,7 @@ def get_container():
return document.getElementById(CONTAINER)
def create_misc_panel(container):
def create_misc_panel(container, apply_func, cancel_func):
container.appendChild(E.div(id=CONTAINER, style='margin: 1rem'))
container = container.lastChild
sd = get_session_data()
@ -48,9 +49,7 @@ def create_misc_panel(container):
container.append(cb('singleinstance', _('Allow only a single instance of the viewer (needs restart)')))
container.append(cb('hide_tooltips', _('Hide mouse-over tooltips in the book text')))
container.appendChild(E.div(
style='margin-top: 1rem', create_button(_('Restore defaults'), action=restore_defaults)
))
container.appendChild(create_button_box(restore_defaults, apply_func, cancel_func))
develop = create_misc_panel

View File

@ -7,7 +7,7 @@ from gettext import gettext as _
from book_list.globals import get_session_data
from dom import unique_id
from widgets import create_button
from read_book.prefs.utils import create_button_box
from session import defaults
CONTAINER = unique_id('standalone-scrolling-settings')
@ -23,7 +23,7 @@ def get_container():
return document.getElementById(CONTAINER)
def create_scrolling_panel(container):
def create_scrolling_panel(container, apply_func, cancel_func):
container.appendChild(E.div(id=CONTAINER, style='margin: 1rem'))
container = container.lastChild
sd = get_session_data()
@ -45,9 +45,7 @@ def create_scrolling_panel(container):
container.appendChild(cb(
'book_scrollbar', _('Show a scrollbar')))
container.appendChild(E.div(
style='margin-top: 1rem', create_button(_('Restore defaults'), action=restore_defaults)
))
container.appendChild(create_button_box(restore_defaults, apply_func, cancel_func))
develop = create_scrolling_panel

View File

@ -6,11 +6,12 @@ from elementmaker import E
from gettext import gettext as _
from book_list.globals import get_session_data
from dom import ensure_id, unique_id
from read_book.globals import runtime, ui_operations
from read_book.prefs.utils import create_button_box
from session import defaults
from viewer.constants import READER_BACKGROUND_URL
from widgets import create_button
from dom import unique_id
BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
@ -72,8 +73,20 @@ def background_fade_widget(sd):
))
def create_user_stylesheet_panel(container):
def restore_defaults():
container = document.getElementById(create_user_stylesheet_panel.container_id)
container.querySelector('[name=user-stylesheet]').value = ''
if runtime.is_standalone_viewer:
clear_image(container.querySelector('img').id)
else:
container.querySelector('[name=background_image]').value = ''
container.querySelector('select[name=background_image_style]').value = defaults.background_image_style
container.querySelector('input[name=background_image_fade]').value = str(defaults.background_image_fade)
def create_user_stylesheet_panel(container, apply_func, cancel_func):
sd = get_session_data()
create_user_stylesheet_panel.container_id = ensure_id(container)
container.appendChild(
E.div(
style='min-height: 75vh; display: flex; flex-flow: column; margin: 1ex 1rem; padding: 1ex 0',
@ -99,6 +112,8 @@ def create_user_stylesheet_panel(container):
val = sd.get('user_stylesheet')
if val:
container.querySelector('[name=user-stylesheet]').value = val
container.appendChild(E.div(style='margin: 1rem', create_button_box(restore_defaults, apply_func, cancel_func)))
develop = create_user_stylesheet_panel

View File

@ -0,0 +1,25 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import bound_methods, hash_literals
from elementmaker import E
from gettext import gettext as _
from widgets import create_button
def create_button_box(restore_defaults_func, apply_func, cancel_func):
cbutton = create_button(_('Cancel'), action=cancel_func)
if restore_defaults_func:
rbutton = create_button(_('Restore defaults'), action=restore_defaults_func)
else:
rbutton = restore_defaults_func or E.div('\xa0')
cbutton.style.marginLeft = '1rem'
return E.div(
style='margin-top: 1rem; display: flex; justify-content: space-between',
rbutton,
E.div(
create_button(_('OK'), action=apply_func),
cbutton
),
)