mirror of
https://github.com/libratbag/piper.git
synced 2026-05-19 12:26:00 -04:00
@@ -3,7 +3,7 @@
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<template class="ButtonDialog" parent="GtkDialog">
|
||||
<property name="width_request">400</property>
|
||||
<property name="width_request">600</property>
|
||||
<property name="height_request">300</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
@@ -43,15 +43,15 @@
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="button_mappings">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="max_content_height">300</property>
|
||||
<property name="min_content_height">250</property>
|
||||
<property name="max_content_width">0</property>
|
||||
<property name="max_content_height">250</property>
|
||||
<property name="propagate_natural_width">True</property>
|
||||
<property name="propagate_natural_height">True</property>
|
||||
<child>
|
||||
@@ -59,64 +59,94 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="listbox">
|
||||
<property name="width_request">250</property>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="row-activated" handler="_on_row_activated" swapped="no"/>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="row_keystroke">
|
||||
<property name="width_request">100</property>
|
||||
<object class="GtkSearchBar" id="search_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Capture a macro for this button</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Search for a button mapping</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkSearchEntry" id="search_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">6</property>
|
||||
<property name="margin_right">6</property>
|
||||
<property name="margin_top">4</property>
|
||||
<property name="margin_bottom">4</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="width_chars">30</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="listbox">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="row-activated" handler="_on_row_activated" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkListBoxRow" id="row_keystroke">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Capture a macro for this button</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_keystroke">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The currently set macro</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="label" translatable="yes">None</property>
|
||||
<property name="track_visited_links">False</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<property name="margin_left">6</property>
|
||||
<property name="margin_right">6</property>
|
||||
<property name="margin_top">4</property>
|
||||
<property name="margin_bottom">4</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_keystroke">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">The currently set macro</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="label" translatable="yes">None</property>
|
||||
<property name="track_visited_links">False</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Send keystroke</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Send keystroke</property>
|
||||
<property name="track_visited_links">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -272,6 +302,8 @@
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
@@ -355,9 +387,6 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel">
|
||||
<property name="visible">True</property>
|
||||
@@ -383,4 +412,60 @@
|
||||
<action-widget response="apply" default="true">apply</action-widget>
|
||||
</action-widgets>
|
||||
</template>
|
||||
<object class="GtkBox" id="empty_search_placeholder">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="border_width">18</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixel_size">72</property>
|
||||
<property name="icon_name">edit-find-symbolic</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">No button mapping found</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.4399999999999999"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Try a different search</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -56,6 +56,10 @@ class ButtonRow(Gtk.ListBoxRow):
|
||||
self.init_template()
|
||||
self.description_label.set_text(description)
|
||||
|
||||
@GObject.Property
|
||||
def description(self):
|
||||
return self.description_label.get_text()
|
||||
|
||||
|
||||
@GtkTemplate(ui="/org/freedesktop/Piper/ui/ButtonDialog.ui")
|
||||
class ButtonDialog(Gtk.Dialog):
|
||||
@@ -76,6 +80,9 @@ class ButtonDialog(Gtk.Dialog):
|
||||
swap_primaries = GtkTemplate.Child()
|
||||
radio_right_handed = GtkTemplate.Child()
|
||||
radio_left_handed = GtkTemplate.Child()
|
||||
empty_search_placeholder = GtkTemplate.Child()
|
||||
search_entry = GtkTemplate.Child()
|
||||
search_bar = GtkTemplate.Child()
|
||||
|
||||
def __init__(self, ratbagd_button, buttons, *args, **kwargs):
|
||||
"""Instantiates a new ButtonDialog.
|
||||
@@ -129,6 +136,10 @@ class ButtonDialog(Gtk.Dialog):
|
||||
def _init_other_buttons_ui(self, buttons):
|
||||
# Shows the listbox to map non-primary buttons.
|
||||
self.listbox.set_header_func(self._listbox_header_func)
|
||||
self.listbox.set_filter_func(self._listbox_filter_func)
|
||||
self.listbox.set_placeholder(self.empty_search_placeholder)
|
||||
self.search_entry.connect("notify::text", lambda o, p: self.listbox.invalidate_filter())
|
||||
|
||||
i = 0
|
||||
for button in buttons:
|
||||
key, name = self._get_button_name_and_description(button)
|
||||
@@ -183,6 +194,22 @@ class ButtonDialog(Gtk.Dialog):
|
||||
row.set_header(box)
|
||||
box.show_all()
|
||||
|
||||
def _listbox_filter_func(self, row):
|
||||
# Filters the list box with the text from the search entry.
|
||||
if self.search_entry.get_text_length() == 0:
|
||||
return True
|
||||
|
||||
if row is not self.row_keystroke:
|
||||
description = row.description.casefold()
|
||||
else:
|
||||
description = _("Send Keystroke").casefold()
|
||||
search = self.search_entry.get_text().casefold()
|
||||
|
||||
for term in search.split(" "):
|
||||
if term not in description:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_button_name_and_description(self, button):
|
||||
name = _("Button {} click").format(button.index)
|
||||
if button.index in RatbagdButton.BUTTON_DESCRIPTION:
|
||||
@@ -227,18 +254,24 @@ class ButtonDialog(Gtk.Dialog):
|
||||
self.grab_remove()
|
||||
|
||||
def do_key_press_event(self, event):
|
||||
# Overrides Gtk.Window's standard key press event callback, so we can
|
||||
# capture the pressed buttons in capture mode. If we're not in capture
|
||||
# mode, we trigger the search bar on any key press.
|
||||
if self.stack.get_visible_child_name() == "overview":
|
||||
return Gtk.Widget.do_key_press_event(self, event)
|
||||
if self.search_bar.handle_event(event) == Gdk.EVENT_STOP:
|
||||
return Gdk.EVENT_STOP
|
||||
return Gtk.Window.do_key_press_event(self, event)
|
||||
return self._do_key_event(event)
|
||||
|
||||
def do_key_release_event(self, event):
|
||||
# Overrides Gtk.Window's standard key release event callback, so we can
|
||||
# capture the released buttons in capture mode. If we're not in capture
|
||||
# mode, we pass the event on to other widgets in the dialog.
|
||||
if self.stack.get_visible_child_name() == "overview":
|
||||
return Gtk.Widget.do_key_release_event(self, event)
|
||||
return Gtk.Window.do_key_release_event(self, event)
|
||||
return self._do_key_event(event)
|
||||
|
||||
def _do_key_event(self, event):
|
||||
# Overrides Gtk.Widget's standard key press event callback, so we can
|
||||
# capture the pressed keys in capture mode.
|
||||
# Normalize tab.
|
||||
if event.keyval == Gdk.KEY_ISO_Left_Tab:
|
||||
event.keyval = Gdk.KEY_Tab
|
||||
|
||||
Reference in New Issue
Block a user