gui: initial
This commit is contained in:
8
Makefile
8
Makefile
@@ -5,5 +5,11 @@ install:
|
||||
cp alacritty_config.py ${INSTALL_DIR}/alacritty-config
|
||||
chmod u+x ${INSTALL_DIR}/alacritty-config
|
||||
|
||||
gui:
|
||||
pip3 install -Ur requirements.txt
|
||||
cp alacritty_config_gui.py ${INSTALL_DIR}/alacritty-config-gui
|
||||
chmod u+x ${INSTALL_DIR}/alacritty-config-gui
|
||||
|
||||
uninstall:
|
||||
rm ${INSTALL_DIR}/alacritty-config
|
||||
rm -f ${INSTALL_DIR}/alacritty-config
|
||||
rm -f ${INSTALL_DIR}/alacritty-config-gui
|
||||
|
@@ -50,9 +50,8 @@ $ alacritty-config tabspaces '"delete"'
|
||||
|
||||
## TODO
|
||||
|
||||
Oh, so much! Ideally, I’d like a GUI at least for all the colorful properties and for
|
||||
selecting fonts. For now the tool is simple and usable enough to be useful, but a simple
|
||||
GUI would definitely give this a better UX. Another time.
|
||||
I’m writing a GUI for the configuration currently, but it’s far from complete. The parts
|
||||
that are already wrapped should work, though!
|
||||
|
||||
<hr/>
|
||||
|
||||
|
272
alacritty_config_gui.py
Normal file
272
alacritty_config_gui.py
Normal file
@@ -0,0 +1,272 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
|
||||
|
||||
ALACRITTY_CONFIG = os.path.expanduser("~/.config/alacritty/alacritty.yml")
|
||||
|
||||
|
||||
class ColorSelect(QtWidgets.QPushButton):
|
||||
def __init__(self, value):
|
||||
super().__init__()
|
||||
self.set_value(value.replace('0x', '#'))
|
||||
self.pressed.connect(self.handle_pressed)
|
||||
|
||||
def handle_pressed(self):
|
||||
color = QtWidgets.QColorDialog.getColor()
|
||||
|
||||
if color.isValid():
|
||||
self.set_value(color.name())
|
||||
|
||||
def set_value(self, value):
|
||||
self._value = value
|
||||
color = QtGui.QColor(self._value)
|
||||
self.setFlat(True)
|
||||
self.setAutoFillBackground(True)
|
||||
self.setStyleSheet("""
|
||||
QPushButton {{
|
||||
color: {0};
|
||||
background-color: {0};
|
||||
border-style: outset;
|
||||
}}
|
||||
QPushButton:checked{{
|
||||
color: {0};
|
||||
background-color: {0};
|
||||
border-style: outset;
|
||||
}}
|
||||
QPushButton:hover{{
|
||||
background-color: {0};
|
||||
border-style: outset;
|
||||
}}
|
||||
""".format(color.name()))
|
||||
self.update()
|
||||
|
||||
def value(self):
|
||||
return self._value.replace('#', '0x')
|
||||
|
||||
|
||||
class ConfigWidget(QtWidgets.QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.widgets = {}
|
||||
|
||||
def prettify(self, s):
|
||||
return ' '.join(x.capitalize() for x in s.split('_') if x)
|
||||
|
||||
def render_state(self):
|
||||
self.layout = QtWidgets.QVBoxLayout()
|
||||
for name, widget in self.widgets.items():
|
||||
sub_layout = QtWidgets.QHBoxLayout()
|
||||
sub_layout.addWidget(QtWidgets.QLabel(self.prettify(name)))
|
||||
sub_layout.addWidget(widget)
|
||||
self.layout.addLayout(sub_layout)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def gather_state(self):
|
||||
state = {}
|
||||
for name, widget in self.widgets.items():
|
||||
path = name.split('__')
|
||||
mut_state = state
|
||||
for elem in path[:-1]:
|
||||
if elem not in mut_state:
|
||||
mut_state[elem] = {}
|
||||
mut_state = mut_state[elem]
|
||||
typ = type(widget)
|
||||
name = path[-1]
|
||||
if typ is QtWidgets.QComboBox:
|
||||
mut_state[name] = widget.currentText()
|
||||
elif typ is QtWidgets.QCheckBox:
|
||||
mut_state[name] = widget.isChecked()
|
||||
elif typ is QtWidgets.QLineEdit:
|
||||
mut_state[name] = widget.text()
|
||||
else:
|
||||
mut_state[name] = widget.value()
|
||||
return state
|
||||
|
||||
|
||||
class Debug(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.widgets['render_timer'] = QtWidgets.QCheckBox()
|
||||
self.widgets['render_timer'].setCheckState(config.get('render_timer'))
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Env(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.widgets['TERM'] = QtWidgets.QLineEdit(config.get('TERM'))
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Selection(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.widgets['semantic_escape_chars'] = QtWidgets.QLineEdit(
|
||||
config.get('semantic_escape_chars')
|
||||
)
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Shell(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.widgets['program'] = QtWidgets.QLineEdit(config.get('program'))
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Font(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
glyph_offset_x = QtWidgets.QSpinBox()
|
||||
glyph_offset_x.setValue(config.get('glyph_offset', {}).get('x'))
|
||||
glyph_offset_y = QtWidgets.QSpinBox()
|
||||
glyph_offset_y.setValue(config.get('glyph_offset', {}).get('y'))
|
||||
scale_with_dpi = QtWidgets.QCheckBox()
|
||||
scale_with_dpi.setChecked(config.get('scale_with_dpi'))
|
||||
size = QtWidgets.QDoubleSpinBox()
|
||||
size.setValue(config.get('size'))
|
||||
use_thin_strokes = QtWidgets.QCheckBox()
|
||||
use_thin_strokes.setChecked(config.get('use_thin_strokes'))
|
||||
|
||||
self.widgets = {
|
||||
'glyph_offset__x': glyph_offset_x,
|
||||
'glyph_offset__y': glyph_offset_y,
|
||||
'scale_with_dpi': scale_with_dpi,
|
||||
'size': size,
|
||||
'use_thin_strokes': use_thin_strokes,
|
||||
}
|
||||
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Colors(ConfigWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
|
||||
primary_background = ColorSelect(
|
||||
config.get('primary', {}).get('background')
|
||||
)
|
||||
primary_foreground = ColorSelect(
|
||||
config.get('primary', {}).get('foreground')
|
||||
)
|
||||
|
||||
self.widgets = {
|
||||
'primary__background': primary_background,
|
||||
'primary__foreground': primary_foreground,
|
||||
}
|
||||
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Window(ConfigWidget):
|
||||
# TODO: transparent and buttonless only on OS X
|
||||
decoration_options = ['full', 'none', 'transparent', 'buttonless']
|
||||
|
||||
# TODO: simplewindowed only on OS X
|
||||
startup_options = ['Windowed', 'FullScreen', 'SimpleWindowed', 'Maximized']
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
decorations = QtWidgets.QComboBox()
|
||||
for option in self.decoration_options:
|
||||
decorations.addItem(option)
|
||||
dec = config.get('decorations')
|
||||
if dec in self.decoration_options:
|
||||
decorations.setCurrentIndex(self.decoration_options.index(dec))
|
||||
|
||||
startup_mode = QtWidgets.QComboBox()
|
||||
for mode in self.startup_options:
|
||||
startup_mode.addItem(mode)
|
||||
dec = config.get('startup_mode')
|
||||
if dec in self.startup_options:
|
||||
startup_mode.setCurrentIndex(self.startup_options.index(dec))
|
||||
|
||||
columns = QtWidgets.QSpinBox()
|
||||
columns.setValue(config.get('dimensions', {}).get('columns'))
|
||||
lines = QtWidgets.QSpinBox()
|
||||
lines.setValue(config.get('dimensions', {}).get('lines'))
|
||||
|
||||
padding_x = QtWidgets.QSpinBox()
|
||||
padding_x.setValue(config.get('padding', {}).get('x'))
|
||||
padding_y = QtWidgets.QSpinBox()
|
||||
padding_y.setValue(config.get('padding', {}).get('y'))
|
||||
|
||||
dynamic_padding = QtWidgets.QCheckBox()
|
||||
dynamic_padding.setChecked(config.get('dynamic_padding', False))
|
||||
|
||||
self.widgets = {
|
||||
'decorations': decorations,
|
||||
'startup_mode': startup_mode,
|
||||
'dimensions__columns': columns,
|
||||
'dimensions__lines': lines,
|
||||
'padding__x': padding_x,
|
||||
'padding__y': padding_y,
|
||||
'dynamic_padding': dynamic_padding,
|
||||
}
|
||||
|
||||
self.render_state()
|
||||
|
||||
|
||||
class Config(QtWidgets.QWidget):
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.layout = QtWidgets.QVBoxLayout()
|
||||
self.config = config
|
||||
self.add_tabs(config)
|
||||
self.add_buttons()
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def add_tabs(self, config):
|
||||
self.tabs = QtWidgets.QTabWidget()
|
||||
|
||||
self.tabs.addTab(Window(config.get('window')), "Window")
|
||||
self.tabs.addTab(Font(config.get('font')), "Font")
|
||||
self.tabs.addTab(Debug(config.get('debug')), "Debug")
|
||||
self.tabs.addTab(Env(config.get('env')), "Env")
|
||||
self.tabs.addTab(Selection(config.get('selection')), "Selection")
|
||||
self.tabs.addTab(Shell(config.get('shell')), "Shell")
|
||||
self.tabs.addTab(Colors(config.get('colors')), "Colors")
|
||||
|
||||
self.layout.addWidget(self.tabs)
|
||||
|
||||
def add_buttons(self):
|
||||
self.buttons = QtWidgets.QDialogButtonBox()
|
||||
ok_button = self.buttons.addButton(self.buttons.Ok)
|
||||
self.buttons.addButton(self.buttons.Cancel)
|
||||
self.buttons.accepted.connect(self.save)
|
||||
self.buttons.rejected.connect(sys.exit)
|
||||
self.layout.addWidget(self.buttons)
|
||||
|
||||
def gather_state(self):
|
||||
state = self.config
|
||||
|
||||
for idx in range(self.tabs.count()):
|
||||
tab = self.tabs.widget(idx)
|
||||
title = self.tabs.tabText(idx).lower()
|
||||
state[title] = {**state.get(title, {}), **tab.gather_state()}
|
||||
|
||||
return state
|
||||
|
||||
def save(self):
|
||||
state = self.gather_state()
|
||||
print(yaml.dump(state))
|
||||
with open(ALACRITTY_CONFIG, 'w+') as f:
|
||||
f.write(yaml.dump(state))
|
||||
sys.exit()
|
||||
|
||||
def addDialog(self):
|
||||
dialog = QtWidgets.QColorDialog()
|
||||
dialog.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication([])
|
||||
with open(ALACRITTY_CONFIG) as f:
|
||||
config = yaml.safe_load(f.read())
|
||||
conf = Config(config)
|
||||
conf.show()
|
||||
app.exec_()
|
Reference in New Issue
Block a user