diff --git a/ignis/widgets/__init__.py b/ignis/widgets/__init__.py index ba51ae6f..0f630d33 100644 --- a/ignis/widgets/__init__.py +++ b/ignis/widgets/__init__.py @@ -19,6 +19,7 @@ from .file_filter import FileFilter from .file_dialog import FileDialog from .grid import Grid +from .popover_menu_bar import PopoverMenuBar from .popover_menu import PopoverMenu from .eventbox import EventBox from .headerbar import HeaderBar @@ -107,6 +108,7 @@ class Widget: "ListBoxRow", "Overlay", "Picture", + "PopoverMenuBar", "PopoverMenu", "RegularWindow", "Revealer", diff --git a/ignis/widgets/popover_menu.py b/ignis/widgets/popover_menu.py index 0ec19fb6..4a60f2be 100644 --- a/ignis/widgets/popover_menu.py +++ b/ignis/widgets/popover_menu.py @@ -56,6 +56,7 @@ def __init__(self, **kwargs): Gtk.PopoverMenu.__init__(self) self._model: IgnisMenuModel | None = None BaseWidget.__init__(self, visible=False, **kwargs) + self._nested = False @IgnisProperty def model(self) -> IgnisMenuModel | None: @@ -71,6 +72,22 @@ def model(self, value: IgnisMenuModel) -> None: self._model = value self.set_menu_model(value.gmenu) + + @IgnisProperty + def nested(self) -> bool: + """ + Whether or not submenus are presented as traditional, nested popovers. + """ + return self._nested + + @nested.setter + def nested(self, value: bool) -> None: + if value: + self.set_flags(Gtk.PopoverMenuFlags.NESTED) + else: + self.set_flags(Gtk.PopoverMenuFlags.SLIDING) + self._nested = value + def __del__(self) -> None: if self._model: diff --git a/ignis/widgets/popover_menu_bar.py b/ignis/widgets/popover_menu_bar.py new file mode 100644 index 00000000..4619a6ba --- /dev/null +++ b/ignis/widgets/popover_menu_bar.py @@ -0,0 +1,73 @@ +from gi.repository import Gtk # type: ignore +from ignis.base_widget import BaseWidget +from ignis.gobject import IgnisProperty +from ignis.menu_model import IgnisMenuModel + + +class PopoverMenuBar(Gtk.PopoverMenuBar, BaseWidget): + """ + Bases: :class:`Gtk.PopoverMenuBar` + + A dropdown menu bar. + + Args: + **kwargs: Properties to set. + + .. code-block:: python + + from ignis.menu_model import IgnisMenuModel, IgnisMenuItem, IgnisMenuSeparator + + widgets.PopoverMenuBar( + model=IgnisMenuModel( + IgnisMenuItem( + label="Just item", + on_activate=lambda x: print("item activated!"), + ), + IgnisMenuItem( + label="This is disabled item", + enabled=False, + on_activate=lambda x: print( + "you will not see this message in terminal hehehehehe" + ), + ), + IgnisMenuModel( + *( # unpacking because items must be passed as *args + IgnisMenuItem( + label=str(i), + on_activate=lambda x, i=i: print(f"Clicked on item {i}!"), + ) + for i in range(10) + ), + label="Submenu", # pass label as keyword argument + ), + ), + ) + """ + + __gtype_name__ = "IgnisPopoverMenuBar" + __gproperties__ = {**BaseWidget.gproperties} + + def __init__(self, **kwargs): + Gtk.PopoverMenuBar.__init__(self) + self._model: IgnisMenuModel | None = None + BaseWidget.__init__(self, **kwargs) + + @IgnisProperty + def model(self) -> IgnisMenuModel | None: + """ + A menu model. + """ + return self._model + + @model.setter + def model(self, value: IgnisMenuModel) -> None: + if self._model: + self._model.clean_gmenu() + + self._model = value + self.set_menu_model(value.gmenu) + + def __del__(self) -> None: + if self._model: + self._model.clean_gmenu() + self._model = None