UI for changing keyboard shortcuts is done

This commit is contained in:
Kovid Goyal 2019-08-25 17:22:44 +05:30
parent e91e414687
commit c106d48163
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 120 additions and 11 deletions

View File

@ -153,7 +153,7 @@ class IframeBoss:
self._handle_gesture = paged_handle_gesture
self.anchor_funcs = paged_anchor_funcs
update_settings(data.settings)
self.keyboard_shortcut_map = create_shortcut_map(data.keyboard_shortcuts)
self.keyboard_shortcut_map = create_shortcut_map(data.settings.keyboard_shortcuts)
set_current_spine_item({'name':data.name, 'is_first':index is 0, 'is_last':index is spine.length - 1, 'initial_position':data.initial_position})
self.last_cfi = None
for name in self.blob_url_map:

View File

@ -7,8 +7,10 @@ from gettext import gettext as _
from book_list.globals import get_session_data
from book_list.item_list import create_item, create_item_list
from dom import unique_id
from read_book.shortcuts import GROUP_DESC, SHORTCUTS
from dom import clear, svgicon, unique_id
from read_book.shortcuts import (
GROUP_DESC, SHORTCUTS, key_as_text, keyevent_as_shortcut, shortcut_differs
)
from widgets import create_button
@ -17,7 +19,10 @@ def get_container():
def restore_defaults():
pass
for item in get_container().querySelectorAll('[data-user-data]'):
q = JSON.parse(item.dataset.userData)
q.shortcuts = SHORTCUTS[q.name].shortcuts
item.dataset.userData = JSON.stringify(q)
def as_groups(shortcuts):
@ -34,21 +39,92 @@ def sort_group_key(group, sc_name):
return group[sc_name].short.toLowerCase()
def sc_as_item(sc_name, sc):
return create_item(sc.short, action=customize_shortcut.bind(None, sc_name), subtitle=sc.long, data=JSON.stringify({'name': sc_name, 'shortcuts': sc.shortcuts}))
def sc_as_item(sc_name, sc, shortcuts):
cuts = shortcuts or sc.shortcuts
return create_item(sc.short, action=customize_shortcut.bind(None, sc_name), subtitle=sc.long, data=JSON.stringify({'name': sc_name, 'shortcuts': cuts}))
def remove_key(evt):
key_container = evt.currentTarget.parentNode.parentNode
key_container.parentNode.removeChild(key_container)
def key_widget(key):
return E.tr(
data_shortcut=JSON.stringify(keyevent_as_shortcut(key)),
E.td(style="padding: 0.5rem; border-right: solid 3px; margin-right: 0.5rem; margin-top: 0.5rem", key_as_text(key)),
E.td(E.a(class_='simple-link', '\xa0', svgicon('remove'), ' ', _('Remove'), onclick=remove_key)),
)
def close_customize_shortcut(apply_changes):
container = get_container()
container.firstChild.style.display = 'block'
container.lastChild.style.display = 'none'
if apply_changes:
shortcuts = v'[]'
for x in container.lastChild.querySelectorAll('[data-shortcut]'):
sc = JSON.parse(x.dataset.shortcut)
shortcuts.push(sc)
sc_name = container.lastChild.dataset.scName
for item in container.querySelectorAll('[data-user-data]'):
q = JSON.parse(item.dataset.userData)
if q.name is sc_name:
q.shortcuts = shortcuts
item.dataset.userData = JSON.stringify(q)
break
def add_key_widget():
uid = unique_id('add-new-shortcut')
return E.div(style='margin-top: 1ex; margin-bottom: 1ex',
id=uid,
E.div(create_button(_('Add a new shortcut'), icon="plus", action=def (evt):
div = document.getElementById(uid)
div.firstChild.style.display = 'none'
div.lastChild.style.display = 'block'
div.lastChild.querySelector('input').focus()
)),
E.div(style='display:none',
E.input(readonly='readonly',
value=_('Press the key combination to use as a shortcut'),
style='width: 90vw',
onkeydown=def (evt):
evt.preventDefault()
evt.stopPropagation()
if evt.key not in v"['Control', 'Meta', 'Alt', 'Shift']":
key_con = get_container().querySelector('.key-container')
key_con.appendChild(key_widget(evt))
div = document.getElementById(uid)
div.firstChild.style.display = 'block'
div.lastChild.style.display = 'none'
))
)
def customize_shortcut(sc_name):
container = get_container()
container.firstChild.style.display = 'none'
container.lastChild.style.display = 'block'
shortcuts = v'[]'
for item in container.querySelectorAll('[data-user-data]'):
q = JSON.parse(item.dataset.userData)
if q.name is sc_name:
shortcuts = q.shortcuts
break
container = container.lastChild
clear(container)
container.dataset.scName = sc_name
sc = SHORTCUTS[sc_name]
container.appendChild(E.h4(sc.short))
if sc.long:
container.appendChild(E.div(sc.long, style='font-style: italic; font-size: smaller; margin-top: 1ex'))
container.appendChild(E.div(_('Existing shortcuts:')))
for key in sc.shortcuts:
container.appendChild(E.div(style='margin-top: 1ex', key_widget(key)))
container.appendChild(E.div(style='margin-top: 1rem', _('Existing shortcuts:')))
key_con = container.appendChild(E.table(class_="key-container"))
for key in shortcuts:
key_con.appendChild(key_widget(key))
container.appendChild(E.div(style='margin-top:1ex;', add_key_widget()))
container.appendChild(E.div(style='margin-top:1ex; display:flex; justify-content: flex-end',
create_button(_('OK'), action=close_customize_shortcut.bind(None, True)),
E.span('\xa0'),
@ -64,6 +140,8 @@ def create_keyboard_panel(container):
container.appendChild(E.div())
container.appendChild(E.div(style='display: none'))
container = container.firstChild
sd = get_session_data()
custom_shortcuts = sd.get('keyboard_shortcuts')
groups = as_groups(SHORTCUTS)
items = []
for group_name in Object.keys(groups):
@ -71,7 +149,7 @@ def create_keyboard_panel(container):
group = groups[group_name]
for sc_name in sorted(Object.keys(group), key=sort_group_key.bind(None, group)):
sc = group[sc_name]
items.push(sc_as_item(sc_name, sc))
items.push(sc_as_item(sc_name, sc, custom_shortcuts[sc_name]))
container.appendChild(E.div())
create_item_list(container.lastChild, items)
@ -83,7 +161,20 @@ def create_keyboard_panel(container):
develop = create_keyboard_panel
def shortcuts_differ(a, b):
if a.length is not b.length:
return True
for x, y in zip(a, b):
if shortcut_differs(x, y):
return True
return False
def commit_keyboard(onchange):
sd = get_session_data()
vals = {}
sd.set('standalone_misc_settings', vals)
for item in get_container().querySelectorAll('[data-user-data]'):
q = JSON.parse(item.dataset.userData)
if shortcuts_differ(q.shortcuts, SHORTCUTS[q.name].shortcuts):
vals[q.name] = q.shortcuts
sd.set('keyboard_shortcuts', vals)

View File

@ -41,6 +41,10 @@ def keyevent_as_shortcut(evt):
}
def shortcut_differs(a, b):
return not (a.key is b.key and a.altKey is b.altKey and a.ctrlKey is b.ctrlKey and a.metaKey is b.metaKey and a.shiftKey is b.shiftKey)
def keyevent_to_index(evt):
parts = v'[]'
for mod in v"['altKey', 'ctrlKey', 'metaKey', 'shiftKey']":
@ -48,6 +52,20 @@ def keyevent_to_index(evt):
return parts.join('') + evt.key
def key_as_text(evt):
mods = v'[]'
for x in ('alt', 'ctrl', 'meta', 'shift'):
if evt[x + 'Key']:
mods.push(x.capitalize())
mods = '+'.join(mods)
if mods:
mods += '+'
key = evt.key
if key is ' ':
key = 'Space'
return mods + key
GROUP_DESC = {
'scroll': _('Navigation')
}