gui: add keybindings
This commit is contained in:
@@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user