mirror of
https://github.com/libratbag/piper.git
synced 2026-05-19 04:16:08 -04:00
Add ButtonsPage to configure buttons
This commit adds the initial buttons page and a skeleton configuration dialog to configure button mappings.
This commit is contained in:
committed by
Peter Hutterer
parent
b08d45550b
commit
96a77f024b
@@ -4,6 +4,7 @@
|
||||
<file>404.svg</file>
|
||||
|
||||
<file preprocess="xml-stripblanks">AboutDialog.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/ButtonDialog.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/LedDialog.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/OptionButton.ui</file>
|
||||
<file preprocess="xml-stripblanks">ui/ResolutionRow.ui</file>
|
||||
|
||||
163
data/ui/ButtonDialog.ui
Normal file
163
data/ui/ButtonDialog.ui
Normal file
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<template class="ButtonDialog" parent="GtkDialog">
|
||||
<property name="width_request">400</property>
|
||||
<property name="height_request">300</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">12</property>
|
||||
<property name="margin_right">12</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="margin_bottom">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">button</property>
|
||||
<property name="title" translatable="yes">Button Mapping</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">key</property>
|
||||
<property name="title" translatable="yes">Key Mapping</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">special</property>
|
||||
<property name="title" translatable="yes">Key Sequence</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">macro</property>
|
||||
<property name="title" translatable="yes">Custom</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel">
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Ignore any changes made</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stack">stack</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="apply">
|
||||
<property name="label" translatable="yes">Apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Apply any changes made</property>
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="cancel">cancel</action-widget>
|
||||
<action-widget response="apply" default="true">apply</action-widget>
|
||||
</action-widgets>
|
||||
</template>
|
||||
</interface>
|
||||
62
piper/buttondialog.py
Normal file
62
piper/buttondialog.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# Copyright (C) 2017 Jente Hidskes <hjdskes@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from .gi_composites import GtkTemplate
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import GObject, Gtk
|
||||
|
||||
|
||||
@GtkTemplate(ui="/org/freedesktop/Piper/ui/ButtonDialog.ui")
|
||||
class ButtonDialog(Gtk.Dialog):
|
||||
"""A Gtk.Dialog subclass to implement the dialog that shows the
|
||||
configuration options for button mappings."""
|
||||
|
||||
__gtype_name__ = "ButtonDialog"
|
||||
|
||||
_BUTTON_TYPE_TO_PAGE = {
|
||||
RatbagdButton.ACTION_TYPE_BUTTON: "mapping",
|
||||
RatbagdButton.ACTION_TYPE_SPECIAL: "special",
|
||||
RatbagdButton.ACTION_TYPE_KEY: "mapping",
|
||||
RatbagdButton.ACTION_TYPE_MACRO: "macro",
|
||||
}
|
||||
|
||||
stack = GtkTemplate.Child()
|
||||
|
||||
def __init__(self, ratbagd_button, *args, **kwargs):
|
||||
"""Instantiates a new ButtonDialog.
|
||||
|
||||
@param ratbagd_button The button to configure, as ratbagd.RatbagdButton.
|
||||
"""
|
||||
Gtk.Dialog.__init__(self, *args, **kwargs)
|
||||
self.init_template()
|
||||
self._button = ratbagd_button
|
||||
self._action_type = self._button.action_type
|
||||
|
||||
self._init_ui()
|
||||
|
||||
def _init_ui(self):
|
||||
action_types = self._button.action_types
|
||||
for action_type in action_types:
|
||||
page = self._BUTTON_TYPE_TO_PAGE[action_type]
|
||||
self.stack.get_child_by_name(page).set_visible(True)
|
||||
if self._action_type == action_type:
|
||||
self.stack.set_visible_child_name(page)
|
||||
|
||||
@GObject.Property
|
||||
def action_type(self):
|
||||
return self._action_type
|
||||
76
piper/buttonspage.py
Normal file
76
piper/buttonspage.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# Copyright (C) 2017 Jente Hidskes <hjdskes@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from .buttondialog import ButtonDialog
|
||||
from .mousemap import MouseMap
|
||||
from .optionbutton import OptionButton
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class ButtonsPage(Gtk.Box):
|
||||
"""The second stack page, exposing the button configuration."""
|
||||
|
||||
__gtype_name__ = "ButtonsPage"
|
||||
|
||||
def __init__(self, ratbagd_device, *args, **kwargs):
|
||||
"""Instantiates a new ButtonsPage.
|
||||
|
||||
@param ratbag_device The ratbag device to configure, as
|
||||
ratbagd.RatbagdDevice
|
||||
"""
|
||||
Gtk.Box.__init__(self, *args, **kwargs)
|
||||
self._device = ratbagd_device
|
||||
self._init_ui()
|
||||
|
||||
def _init_ui(self):
|
||||
profile = self._find_active_profile()
|
||||
|
||||
mousemap = MouseMap("#Buttons", self._device, spacing=20, border_width=20)
|
||||
self.pack_start(mousemap, True, True, 0)
|
||||
|
||||
sizegroup = Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL)
|
||||
for ratbagd_button in profile.buttons:
|
||||
index = ratbagd_button.index
|
||||
# TODO: add the correct *mapping to the label
|
||||
button = OptionButton(_("Button {}").format(index))
|
||||
button.connect("clicked", self._on_button_clicked, ratbagd_button)
|
||||
mousemap.add(button, "#button{}".format(index))
|
||||
sizegroup.add_widget(button)
|
||||
|
||||
def _on_button_clicked(self, button, ratbagd_button):
|
||||
# Presents the ButtonDialog to configure the mouse button corresponding
|
||||
# to the clicked button.
|
||||
dialog = ButtonDialog(ratbagd_button, transient_for=self.get_toplevel())
|
||||
dialog.connect("response", self._on_dialog_response, ratbagd_button)
|
||||
dialog.present()
|
||||
|
||||
def _on_dialog_response(self, dialog, response, ratbagd_button):
|
||||
# The user either pressed cancel or apply. If it's apply, apply the
|
||||
# changes before closing the dialog, otherwise just close the dialog.
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
print("Apply")
|
||||
dialog.destroy()
|
||||
|
||||
def _find_active_profile(self):
|
||||
# Finds the active profile, which is guaranteed to exist.
|
||||
for profile in self._device.profiles:
|
||||
if profile.is_active:
|
||||
return profile
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from .buttonspage import ButtonsPage
|
||||
from .gi_composites import GtkTemplate
|
||||
from .ratbagd import RatbagErrorCode, RatbagdDevice
|
||||
from .resolutionspage import ResolutionsPage
|
||||
@@ -30,8 +31,8 @@ from gi.repository import GLib, Gtk
|
||||
class Window(Gtk.ApplicationWindow):
|
||||
"""A Gtk.ApplicationWindow subclass to implement the main application
|
||||
window. This Window contains the overlay for the in-app notifications, the
|
||||
headerbar and the stack holding a ResolutionsPage, a ButtonPage and a
|
||||
LEDPage."""
|
||||
headerbar and the stack holding a ResolutionsPage, a ButtonsPage and a
|
||||
LedsPage."""
|
||||
|
||||
__gtype_name__ = "ApplicationWindow"
|
||||
|
||||
@@ -60,6 +61,8 @@ class Window(Gtk.ApplicationWindow):
|
||||
capabilities = self._device.capabilities
|
||||
if RatbagdDevice.CAP_RESOLUTION in capabilities:
|
||||
self.stack.add_titled(ResolutionsPage(self._device), "resolutions", _("Resolutions"))
|
||||
if RatbagdDevice.CAP_BUTTON in capabilities:
|
||||
self.stack.add_titled(ButtonsPage(self._device), "buttons", _("Buttons"))
|
||||
if RatbagdDevice.CAP_LED in capabilities:
|
||||
self.stack.add_titled(LedsPage(self._device), "leds", _("LEDs"))
|
||||
except ValueError as e:
|
||||
|
||||
Reference in New Issue
Block a user