From 3d3b8718e5869d3bf7c702b70c652198c9a8af96 Mon Sep 17 00:00:00 2001 From: elParaguayo Date: Mon, 30 Dec 2024 17:14:57 +0000 Subject: [PATCH] Update docs for popup menus --- docs/_static/images/text_power_menu.png | Bin 0 -> 8470 bytes docs/manual/how_to/popup.rst | 75 ++++++++++++++++++++++-- docs/manual/ref/popup.rst | 19 +++++- qtile_extras/popup/menu.py | 24 ++++++-- 4 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 docs/_static/images/text_power_menu.png diff --git a/docs/_static/images/text_power_menu.png b/docs/_static/images/text_power_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..623aba3b14abc70d9b24119a5767a88bedd05e64 GIT binary patch literal 8470 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 Aod5s; literal 0 HcmV?d00001 diff --git a/docs/manual/how_to/popup.rst b/docs/manual/how_to/popup.rst index 1b2c6b1a..09304210 100644 --- a/docs/manual/how_to/popup.rst +++ b/docs/manual/how_to/popup.rst @@ -35,6 +35,7 @@ Currently, the following controls are provided: - ``PopupText``: a simple text display object - ``PopupImage``: a control to display an image - ``PopupSlider``: a control to draw a line which marks a particular value (e.g. volume level) +- ``PopupCircularProgress``: a control to draw a curved line showing progress etc. - ``PopupWidget``: a control to display a Qtile widget in the popup Configuration options for these controls can be found on @@ -55,7 +56,7 @@ Below is an example of creating a power menu in your ``config.py``. .. code:: python - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupImage, PopupText @@ -154,7 +155,7 @@ Below is a quick example for displaying a number of graph widgets in a popup: .. code:: python from libqtile import widget - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupWidget ) @@ -216,7 +217,7 @@ be updated in the same call. .. code:: python - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupText ) @@ -267,7 +268,7 @@ For example, to make the ``Clock`` widget show the long date when clicked: from libqtile import widget from qtile_extras import widget as extrawidgets - from qtile_extras.popup.toolkit import PopupRelativeLayout, PopupText, PopupWidget + from qtile_extras.popup import PopupRelativeLayout, PopupText, PopupWidget from qtile_extras.widget.mixins import ExtendedPopupMixin @@ -321,4 +322,68 @@ For example, to make the ``Clock`` widget show the long date when clicked: Putting ``extended_clock`` in your bar and clicking on the clock will give you this: -.. image:: /_static/images/extended_popup_clock.png \ No newline at end of file +.. image:: /_static/images/extended_popup_clock.png + + +Building simple text menus +========================== + +The toolkit also contains some basic classes to simplify the creation of text based menus. +The primary use of these classes is to provide context menus for widgets (e.g. ``StatusNotifier``) +but they can also be easily incorporated directly in config files. + +For example, to recreate the power menu above using text, you could define the following: + +.. code:: python + + from libqtile.lazy import lazy + + from qtile_extras.popup import PopupMenu, PopupMenuItem, PopupMenuSeparator + + + @lazy.function + def show_text_power_menu(qtile): + items = [ + PopupMenuItem(text="Power Menu", enabled=False), + PopupMenuSeparator(), + PopupMenuItem( + text="Lock", + mouse_callbacks={ + "Button1": lazy.spawn("/path/to/lock_cmd") + } + ), + PopupMenuItem( + text="Sleep", + mouse_callbacks={ + "Button1": lazy.spawn("/path/to/lock_cmd") + } + ), + PopupMenuItem( + text="Shutdown", + highlight="900", + mouse_callbacks={ + "Button1": lazy.shutdown() + } + ), + ] + menu = PopupMenu.generate(qtile, menuitems=items, border_width=2) + menu.show(centered=True) + + keys = [ + ... + Key([mod, "shift"], "q", show_text_power_menu) + ... + ] + +Pressing ``Mod + shift + B`` will display the following: + +.. image:: /_static/images/text_power_menu.png + +Menu items have a default blue/green highlight but this was overriden to show red for +the shutdown command. + +Note that the menu items can be configured individually. Configuration options for the layout +(border etc.) are passed to the ``generate`` method. + +Configuration options for the menu objects can be found on +:ref:`the reference page `. diff --git a/docs/manual/ref/popup.rst b/docs/manual/ref/popup.rst index 2241d5ae..1b4a4c2b 100644 --- a/docs/manual/ref/popup.rst +++ b/docs/manual/ref/popup.rst @@ -32,4 +32,21 @@ and have each of these react to input events or display information dynamically. :baseclass: qtile_extras.popup.toolkit._PopupWidget :exclude-base: :no-commands: - :show-config: \ No newline at end of file + :show-config: + + +.. _ref-popup-menus: + +Popup Toolkit Menus +=================== + +These are basic text menus. The layout is generated automatically and users are only +required to provide the menu items. + +.. qtile_class:: qtile_extras.popup.menu.PopupMenu + :methods: generate,from_dbus_menu + +.. qtile_class:: qtile_extras.popup.menu.PopupMenuItem + +.. qtile_class:: qtile_extras.popup.menu.PopupMenuSeparator + \ No newline at end of file diff --git a/qtile_extras/popup/menu.py b/qtile_extras/popup/menu.py index 8527b51a..b6a6cefc 100644 --- a/qtile_extras/popup/menu.py +++ b/qtile_extras/popup/menu.py @@ -162,13 +162,13 @@ class PopupMenu(PopupGridLayout): A class for creating menus. The menu should be created via one of two classmethods: - `from_dbus_menu` or `generate`. The former accepts a list of - `DBusMenuItem` objects and the second accepts a list of - `PopupMenuItem` and `PopupMenuSeparator` objects. + ``from_dbus_menu`` or ``generate``. The former accepts a list of + ``DBusMenuItem`` objects and the second accepts a list of + ``PopupMenuItem`` and ``PopupMenuSeparator`` objects. The menu is created as a PopupGridLayout object. Therefore, if - using the `generate` method, object sizes can be changed using - the `row_span` attribute. By default, a text item will be twice + using the ``generate`` method, object sizes can be changed using + the ``row_span`` attribute. By default, a text item will be twice the height of a separator. """ @@ -182,6 +182,12 @@ def __init__(self, qtile, controls, **config): @classmethod def from_dbus_menu(cls, qtile, dbusmenuitems, **config): + """ + Create a ``PopupMenu`` instance a DBus menu. + + The ``dbusmenuitems`` need to be created from ``DBusMenu.parse_menu`` as this + will generate the ``DBusMenuItem`` objects needed to create a menu. + """ menuitems = [] prev_sep = False @@ -227,6 +233,14 @@ def from_dbus_menu(cls, qtile, dbusmenuitems, **config): @classmethod def generate(cls, qtile, menuitems, **config): + """ + Create a ``PopupMenu`` instance from the provided ``menuitems``. + + Users must pass the ``qtile`` instance as well as the list of items. + + ``menuitems`` should be a list of ``PopupMenuItem`` and ``PopupMenuSeparator`` + instances. + """ row_count = 0 for item in menuitems: item.row = row_count