From fd0679a36b4733195ee6e6dba8b70835e4c07f13 Mon Sep 17 00:00:00 2001 From: sezanzeb Date: Tue, 3 Nov 2020 23:41:05 +0100 Subject: [PATCH] more beautiful mapping table --- bin/key-mapper-gtk | 53 +++++++++------- data/key-mapper.glade | 140 ++++++++++++++++++++++++------------------ data/screenshot.png | Bin 20863 -> 17825 bytes data/style.css | 5 ++ keymapper/X.py | 2 + 5 files changed, 118 insertions(+), 82 deletions(-) create mode 100644 data/style.css diff --git a/bin/key-mapper-gtk b/bin/key-mapper-gtk index 930df28e..d8e5fda0 100755 --- a/bin/key-mapper-gtk +++ b/bin/key-mapper-gtk @@ -28,7 +28,7 @@ from argparse import ArgumentParser import gi gi.require_version('Gtk', '3.0') gi.require_version('GLib', '2.0') -from gi.repository import Gtk +from gi.repository import Gtk, Gdk from keymapper.data import get_data_path from keymapper.X import create_setxkbmap_config, apply_preset, create_preset @@ -41,6 +41,9 @@ from keymapper.linux import get_devices window = None +# TODO check for sudo rights + + class SingleKeyMapping: """A single, configurable key mapping.""" def __init__(self, delete_callback): @@ -54,24 +57,27 @@ class SingleKeyMapping: def put_together(self): """Create all GTK widgets.""" - delete_button = Gtk.Button() - destroy_icon = Gtk.Image.new_from_icon_name( + delete_button = Gtk.EventBox() + delete_button.add(Gtk.Image.new_from_icon_name( 'window-close', Gtk.IconSize.BUTTON - ) - delete_button.set_image(destroy_icon) - delete_button.connect('clicked', self.on_delete_button_clicked) + )) + delete_button.connect('button-press-event', self.on_delete_button_clicked) + delete_button.set_margin_start(5) + delete_button.set_margin_end(5) key_code = Gtk.Entry() key_code.set_alignment(0.5) key_code.set_width_chars(4) + key_code.set_has_frame(False) original_key = Gtk.Entry() original_key.set_alignment(0.5) original_key.set_width_chars(4) + original_key.set_has_frame(False) - self.widgets = (delete_button, key_code, original_key) + self.widgets = (key_code, original_key, delete_button) - def on_delete_button_clicked(self, button): + def on_delete_button_clicked(self, *args): """Destroy the row and remove it from the config.""" for widget in self.widgets: widget.destroy() @@ -92,7 +98,7 @@ class Window: builder.connect_signals(self) self.builder = builder - window = builder.get_object('window') + window = self.get('window') window.show() self.window = window @@ -100,6 +106,14 @@ class Window: self.select_newest_preset() + css_provider = Gtk.CssProvider() + css_provider.load_from_path(get_data_path('style.css')) + Gtk.StyleContext.add_provider_for_screen( + Gdk.Screen.get_default(), + css_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ) + def get(self, name): """Get a widget from the window""" return self.builder.get_object(name) @@ -216,23 +230,18 @@ class Window: self.mappings = [] # TODO show all mapped keys from config - self.clear_mapping_table() - - self.on_add_key_clicked() - - def on_add_key_clicked(self, button=None): - """Add a mapping to the list of mappings.""" - # TODO automatically add a line when no line is empty anymore, - # making the add button obsolete single_key_mapping = SingleKeyMapping(self.on_row_removed) key_list = self.get('key_list') - key_list.insert_row(1) + row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + row.set_homogeneous(True) widgets = single_key_mapping.get_widgets() - key_list.attach(widgets[0], 0, 1, 1, 1) - key_list.attach(widgets[1], 1, 1, 1, 1) - key_list.attach(widgets[2], 2, 1, 1, 1) + row.pack_start(widgets[0], expand=True, fill=True, padding=0) + row.pack_start(widgets[1], expand=True, fill=True, padding=0) + row.pack_start(widgets[2], expand=True, fill=True, padding=0) + key_list.insert(row, -1) key_list.show_all() - self.rows += 1 + + self.clear_mapping_table() def on_row_removed(self, mapping): """Stuff to do when a row was removed diff --git a/data/key-mapper.glade b/data/key-mapper.glade index 90f8abc8..879489cd 100644 --- a/data/key-mapper.glade +++ b/data/key-mapper.glade @@ -8,6 +8,48 @@ asdf 0.5 + + True + True + + + True + False + 2 + + + True + False + 10 + 5 + True + Key + 10 + + + 0 + 0 + + + + + True + False + 10 + 5 + True + Mapping + 10 + + + 1 + 0 + + + + 450 False @@ -133,18 +175,6 @@ 2 - - - True - False - 0 - - - True - True - 3 - - gtk-delete @@ -272,38 +302,37 @@ - 200 True False vertical - + True False - 10 + True - 50 True False - Mapping - 0 + 5 + 5 + Key + 10 - True + False True 0 - - gtk-add - 80 + True - True - True - True - + False + 5 + 5 + Mapping + 10 False @@ -311,6 +340,17 @@ 1 + + + True + False + + + False + True + 2 + + False @@ -319,48 +359,28 @@ - + True False - 10 - 10 - 10 - 2 - 2 - - - True - False - True - Mapping - - - 2 - 0 - - - - - True - False - True - Key - - - 1 - 0 - - - - - - True + False True 1 + + + True + False + none + + + True + True + 2 + + False diff --git a/data/screenshot.png b/data/screenshot.png index 25786349fa3e5e8823bc432dd1a4e44dde201a85..3d9384880c70cac65501d8478bae54d5cbe2d5ce 100644 GIT binary patch literal 17825 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' not in keycodes: logger.error(f'Unknown keycode <{code}> for "{character}"') + # continue, otherwise X would crash when loading + continue xkb_symbols.append(f'key <{code}> {{ [ {character} ] }};') if len(xkb_symbols) == 0: logger.error('Failed to populate xkb_symbols')