gui: add keybindings

This commit is contained in:
2019-06-26 12:34:40 +02:00
parent ef7e60f05c
commit 25a96cc991

View File

@@ -12,6 +12,16 @@ ALACRITTY_CONFIG = os.path.expanduser("~/.config/alacritty/alacritty.yml")
NAME = 'Alacritty Config'
def delete_layout_items(layout):
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
delete_layout_items(item.layout())
class ColorSelect(QtWidgets.QPushButton):
def __init__(self, value):
super().__init__()
@@ -159,6 +169,161 @@ class Spoiler(QtWidgets.QWidget):
last.setEndValue(content_height)
class KeyBindingDialog(QtWidgets.QDialog):
action_options = ([
"", "Copy", "Paste", "PasteSelection", "IncreaseFontSize", "DecreaseFontSize",
"ResetFontSize", "ScrollPageUp", "ScrollPageDown", "ScrollLineUp",
"ScrollLineDown", "ScrollToTop", "ScrollToBottom", "ClearHistory", "Hide",
"Quit", "ToggleFullscreen", "SpawnNewInstance", "ClearLogNotice", "None",
] + (['ToggleSimpleFullscreen'] if platform.system() == 'Darwin' else []))
modifier_options = ["Command", "Control", "Option", "Super", "Shift", "Alt"]
def __init__(self):
super().__init__()
self.result = {}
self.layout = QtWidgets.QVBoxLayout()
sub_layout = QtWidgets.QHBoxLayout()
sub_layout.addWidget(QtWidgets.QLabel('Key'))
self.key = QtWidgets.QLineEdit()
sub_layout.addWidget(self.key)
self.layout.addLayout(sub_layout)
sub_layout = QtWidgets.QHBoxLayout()
sub_layout.addWidget(QtWidgets.QLabel('Mods'))
self.mods = QtWidgets.QListWidget()
for option in self.modifier_options:
self.mods.addItem(option)
self.mods.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
sub_layout.addWidget(self.mods)
self.layout.addLayout(sub_layout)
sub_layout = QtWidgets.QHBoxLayout()
sub_layout.addWidget(QtWidgets.QLabel('Action'))
self.action = QtWidgets.QComboBox()
for option in self.action_options:
self.action.addItem(option)
sub_layout.addWidget(self.action)
self.layout.addLayout(sub_layout)
sub_layout = QtWidgets.QHBoxLayout()
sub_layout.addWidget(QtWidgets.QLabel('Chars'))
self.chars = QtWidgets.QLineEdit()
sub_layout.addWidget(self.chars)
self.layout.addLayout(sub_layout)
buttons = QtWidgets.QDialogButtonBox()
buttons.addButton(buttons.Ok)
buttons.addButton(buttons.Cancel)
buttons.accepted.connect(self.do_accept)
buttons.rejected.connect(self.reject)
self.layout.addWidget(buttons)
self.setLayout(self.layout)
def do_accept(self):
key = self.key.text()
# TODO: this is an ugly heuristic. should we parse yaml here?
self.result['key'] = int(key) if key.isdigit() else key
action = self.action.currentText()
if action:
self.result['action'] = action
chars = self.chars.text()
if chars:
self.result['chars'] = chars
mods = self.mods.selectedItems()
if len(mods):
self.result['mods'] = '|'.join(mod.text() for mod in mods)
self.accept()
class KeyBindingsWidget(QtWidgets.QWidget):
def __init__(self, key_bindings):
super().__init__()
self.key_bindings = key_bindings
self.lst = None
self.init()
def init(self):
self.layout = QtWidgets.QVBoxLayout()
self.update()
btn_group = QtWidgets.QHBoxLayout()
btn_group.setAlignment(QtCore.Qt.AlignLeft)
self.layout.addLayout(btn_group)
btn = QtWidgets.QPushButton('+')
btn.setMaximumSize(40, 40)
btn.clicked.connect(self.open_dialog)
btn_group.addWidget(btn)
btn = QtWidgets.QPushButton('-')
btn.setMaximumSize(40, 40)
btn.clicked.connect(self.delete_selected)
btn_group.addWidget(btn)
self.setLayout(self.layout)
def update(self):
if self.lst:
self.lst.setParent(None)
self.lst = QtWidgets.QTableWidget(len(self.key_bindings), 2)
self.lst.setShowGrid(False)
horizontal_header = self.lst.horizontalHeader()
horizontal_header.setVisible(False)
# TODO: why do i need this?
horizontal_header.resizeSection(0, 200)
horizontal_header.resizeSection(1, 200)
self.lst.verticalHeader().setVisible(False)
self.lst.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.lst.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
for i, binding in enumerate(self.key_bindings):
key, action = self.itemize(binding)
self.lst.setItem(i, 0, QtWidgets.QTableWidgetItem(key))
self.lst.setItem(i, 1, QtWidgets.QTableWidgetItem(action))
self.layout.insertWidget(0, self.lst)
def open_dialog(self):
dialog = KeyBindingDialog()
if dialog.exec() == QtWidgets.QDialog.Accepted:
key_binding = dialog.result
self.key_bindings.append(key_binding)
self.update()
def delete_selected(self):
to_delete = set()
for i in self.lst.selectedIndexes():
to_delete.add(i.row())
for i in sorted(to_delete, reverse=True):
del self.key_bindings[i]
self.update()
def itemize(self, binding):
key = binding['key']
mods = binding.get('mods')
if mods:
key = '{} {}'.format(' '.join(mods.split('|')), key)
action = binding.get('action')
command = binding.get('command')
if command:
action = 'cmd({} {})'.format(command['program'], ' '.join(command['args']))
chars = binding.get('chars')
if chars:
action = 'chars({})'.format(chars)
return key, action
def value(self):
return self.key_bindings
class ConfigWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
@@ -515,6 +680,19 @@ class Scrolling(ConfigWidget):
self.render_state()
class KeyBindings(ConfigWidget):
def __init__(self, config):
super().__init__()
keybindings = KeyBindingsWidget(config)
self.widgets = {
'key_bindings': keybindings,
}
self.render_state()
class Config(QtWidgets.QWidget):
def __init__(self, config):
super().__init__()
@@ -536,6 +714,9 @@ class Config(QtWidgets.QWidget):
self.tabs.addTab(Shell(self.config.get('shell', {})), "Shell")
self.tabs.addTab(Colors(self.config.get('colors', {})), "Colors")
self.tabs.addTab(Scrolling(self.config.get('scrolling', {})), "Scrolling")
self.tabs.addTab(
KeyBindings(self.config.get('key_bindings', [])), "Key Bindings"
)
self.layout.addWidget(self.tabs)