""" Components/List =============== .. seealso:: `Material Design spec, Lists `_ .. rubric:: Lists are continuous, vertical indexes of text or images. .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/lists.png :align: center The class :class:`~MDList` in combination with a :class:`~BaseListItem` like :class:`~OneLineListItem` will create a list that expands as items are added to it, working nicely with `Kivy's` :class:`~kivy.uix.scrollview.ScrollView`. Due to the variety in sizes and controls in the `Material Design spec`, this module suffers from a certain level of complexity to keep the widgets compliant, flexible and performant. For this `KivyMD` provides list items that try to cover the most common usecases, when those are insufficient, there's a base class called :class:`~BaseListItem` which you can use to create your own list items. This documentation will only cover the provided ones, for custom implementations please refer to this module's source code. `KivyMD` provides the following list items classes for use: Text only ListItems ------------------- - OneLineListItem_ - TwoLineListItem_ - ThreeLineListItem_ ListItems with widget containers -------------------------------- These widgets will take other widgets that inherit from :class:`~ILeftBody`, :class:`ILeftBodyTouch`, :class:`~IRightBody` or :class:`~IRightBodyTouch` and put them in their corresponding container. As the name implies, :class:`~ILeftBody` and :class:`~IRightBody` will signal that the widget goes into the left or right container, respectively. :class:`~ILeftBodyTouch` and :class:`~IRightBodyTouch` do the same thing, except these widgets will also receive touch events that occur within their surfaces. `KivyMD` provides base classes such as :class:`~ImageLeftWidget`, :class:`~ImageRightWidget`, :class:`~IconRightWidget`, :class:`~IconLeftWidget`, based on the above classes. .. rubric:: Allows the use of items with custom widgets on the left. - OneLineAvatarListItem_ - TwoLineAvatarListItem_ - ThreeLineAvatarListItem_ - OneLineIconListItem_ - TwoLineIconListItem_ - ThreeLineIconListItem_ .. rubric:: It allows the use of elements with custom widgets on the left and the right. - OneLineAvatarIconListItem_ - TwoLineAvatarIconListItem_ - ThreeLineAvatarIconListItem_ - OneLineRightIconListItem_ - TwoLineRightIconListItem_ - ThreeLineRightIconListItem_ Usage ----- .. tabs:: .. tab:: Declarative KV style .. code-block:: python from kivy.lang import Builder from kivymd.app import MDApp from kivymd.uix.list import OneLineListItem KV = ''' MDScrollView: MDList: id: container ''' class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return Builder.load_string(KV) def on_start(self): for i in range(20): self.root.ids.container.add_widget( OneLineListItem(text=f"Single-line item {i}") ) Example().run() .. tab:: Declarative python style .. code-block:: python from kivymd.app import MDApp from kivymd.uix.list import OneLineListItem class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return ( MDScrollView( MDList( id="container" ) ) ) def on_start(self): for i in range(20): self.root.ids.container.add_widget( OneLineListItem(text=f"Single-line item {i}") ) Example().run() .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/lists.gif :align: center Events of List -------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: python from kivy.lang import Builder from kivymd.app import MDApp KV = ''' MDScrollView: MDList: OneLineAvatarIconListItem: on_release: print("Click!") IconLeftWidget: icon: "github" OneLineAvatarIconListItem: on_release: print("Click 2!") IconLeftWidget: icon: "gitlab" ''' class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return Builder.load_string(KV) Example().run() .. tab:: Declarative python style .. code-block:: python from kivymd.app import MDApp from kivymd.uix.scrollview import MDScrollView from kivymd.uix.list import MDList, OneLineAvatarIconListItem, IconLeftWidget class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return ( MDScrollView( MDList( OneLineAvatarIconListItem( IconLeftWidget( icon="github" ), on_release=lambda x: print("Click!") ), OneLineAvatarIconListItem( IconLeftWidget( icon="gitlab" ), on_release=lambda x: print("Click 2!") ), ) ) ) Example().run() .. OneLineListItem: OneLineListItem --------------- .. code-block:: kv OneLineListItem: text: "Single-line item" .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineListItem.png :align: center .. TwoLineListItem: TwoLineListItem --------------- .. code-block:: kv TwoLineListItem: text: "Two-line item" secondary_text: "Secondary text here" .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineListItem.png :align: center .. ThreeLineListItem: ThreeLineListItem ----------------- .. code-block:: kv ThreeLineListItem: text: "Three-line item" secondary_text: "This is a multi-line label where you can" tertiary_text: "fit more text than usual" .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineListItem.png :align: center .. OneLineAvatarListItem: OneLineAvatarListItem --------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineAvatarListItem: text: "Single-line item with avatar" ImageLeftWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python OneLineAvatarListItem( ImageLeftWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineAvatarListItem.png :align: center .. TwoLineAvatarListItem: TwoLineAvatarListItem --------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv TwoLineAvatarListItem: text: "Two-line item with avatar" secondary_text: "Secondary text here" ImageLeftWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python OneLineAvatarListItem( ImageLeftWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", secondary_text: "Secondary text here", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineAvatarListItem.png :align: center .. ThreeLineAvatarListItem: ThreeLineAvatarListItem ----------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv ThreeLineAvatarListItem: text: "Three-line item with avatar" secondary_text: "Secondary text here" tertiary_text: "fit more text than usual" ImageLeftWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python OneLineAvatarListItem( ImageLeftWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", secondary_text: "Secondary text here", tertiary_text: "fit more text than usual" ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineAvatarListItem.png :align: center .. OneLineRightIconListItem: OneLineRightIconListItem ------------------------ .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineRightIconListItem: text: "Single-line item with avatar" ImageRightWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python OneLineRightIconListItem( ImageRightWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineRightIconListItem.png :align: center .. TwoLineRightIconListItem: TwoLineRightIconListItem ------------------------ .. tabs:: .. tab:: Declarative KV style .. code-block:: kv TwoLineRightIconListItem: text: "Single-line item with avatar" secondary_text: "Secondary text here" ImageRightWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python TwoLineRightIconListItem( ImageRightWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", secondary_text: "Secondary text here", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineRightIconListItem.png :align: center .. ThreeLineRightIconListItem: ThreeLineRightIconListItem -------------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv ThreeLineRightIconListItem: text: "Single-line item with avatar" secondary_text: "Secondary text here" tertiary_text: "fit more text than usual" ImageRightWidget: source: "kivymd/images/logo/kivymd-icon-256.png" .. tab:: Declarative python style .. code-block:: python ThreeLineRightIconListItem( ImageRightWidget( source="kivymd/images/logo/kivymd-icon-256.png" ), text="Single-line item with avatar", secondary_text: "Secondary text here", tertiary_text: "fit more text than usual", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineRightIconListItem.png :align: center .. OneLineIconListItem: OneLineIconListItem ------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineIconListItem: text: "Single-line item with avatar" IconLeftWidget: icon: "language-python" .. tab:: Declarative python style .. code-block:: python OneLineIconListItem( IconLeftWidget( icon="language-python" ), text="Single-line item with avatar" ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineIconListItem.png :align: center .. TwoLineIconListItem: TwoLineIconListItem ------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv TwoLineIconListItem: text: "Two-line item with avatar" secondary_text: "Secondary text here" IconLeftWidget: icon: "language-python" .. tab:: Declarative python style .. code-block:: python TwoLineIconListItem( IconLeftWidget( icon="language-python" ), text="Single-line item with avatar", secondary_text: "Secondary text here" ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineIconListItem.png :align: center .. ThreeLineIconListItem: ThreeLineIconListItem --------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv ThreeLineIconListItem: text: "Three-line item with avatar" secondary_text: "Secondary text here" tertiary_text: "fit more text than usual" IconLeftWidget: icon: "language-python" .. tab:: Declarative python style .. code-block:: python ThreeLineIconListItem( IconLeftWidget( icon="language-python" ), text="Single-line item with avatar", secondary_text: "Secondary text here", tertiary_text: "fit more text than usual", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineIconListItem.png :align: center .. OneLineAvatarIconListItem: OneLineAvatarIconListItem ------------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineAvatarIconListItem: text: "One-line item with avatar" IconLeftWidget: icon: "plus" IconRightWidget: icon: "minus" .. tab:: Declarative python style .. code-block:: python OneLineAvatarIconListItem( IconLeftWidget( icon="plus" ), IconRightWidget( icon="minus" ), text="Single-line item with avatar", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineAvatarIconListItem.png :align: center .. TwoLineAvatarIconListItem: TwoLineAvatarIconListItem ------------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv TwoLineAvatarIconListItem: text: "Two-line item with avatar" secondary_text: "Secondary text here" IconLeftWidget: icon: "plus" IconRightWidget: icon: "minus" .. tab:: Declarative python style .. code-block:: python TwoLineAvatarIconListItem( IconLeftWidget( icon="plus" ), IconRightWidget( icon="minus" ), text="Single-line item with avatar", secondary_text: "Secondary text here", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineAvatarIconListItem.png :align: center .. ThreeLineAvatarIconListItem: ThreeLineAvatarIconListItem --------------------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: kv ThreeLineAvatarIconListItem: text: "Three-line item with avatar" secondary_text: "Secondary text here" tertiary_text: "fit more text than usual" IconLeftWidget: icon: "plus" IconRightWidget: icon: "minus" .. tab:: Declarative python style .. code-block:: python ThreeLineAvatarIconListItem( IconLeftWidget( icon="plus" ), IconRightWidget( icon="minus" ), text="Single-line item with avatar", secondary_text: "Secondary text here", tertiary_text: "fit more text than usual", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineAvatarIconListItem.png :align: center Custom list item ---------------- .. tabs:: .. tab:: Declarative KV style .. code-block:: python from kivy.lang import Builder from kivy.properties import StringProperty from kivymd.app import MDApp from kivymd.uix.list import IRightBodyTouch, OneLineAvatarIconListItem from kivymd.uix.selectioncontrol import MDCheckbox from kivymd.icon_definitions import md_icons KV = ''' : IconLeftWidget: icon: root.icon RightCheckbox: MDScrollView: MDList: id: scroll ''' class ListItemWithCheckbox(OneLineAvatarIconListItem): '''Custom list item.''' icon = StringProperty("android") class RightCheckbox(IRightBodyTouch, MDCheckbox): '''Custom right container.''' class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return Builder.load_string(KV) def on_start(self): icons = list(md_icons.keys()) for i in range(30): self.root.ids.scroll.add_widget( ListItemWithCheckbox(text=f"Item {i}", icon=icons[i]) ) Example().run() .. tab:: Declarative python style .. code-block:: python from kivymd.app import MDApp from kivymd.uix.list import IRightBodyTouch, OneLineAvatarIconListItem from kivymd.uix.selectioncontrol import MDCheckbox from kivymd.uix.scrollview import MDScrollView from kivymd.uix.list import MDList from kivymd.icon_definitions import md_icons class RightCheckbox(IRightBodyTouch, MDCheckbox): '''Custom right container.''' class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return ( MDScrollView( MDList( id="scroll" ) ) ) def on_start(self): icons = list(md_icons.keys()) for i in range(30): self.root.ids.scroll.add_widget( OneLineAvatarIconListItem( IconLeftWidget( icon=icons[i] ), RightCheckbox(), text=f"Item {i}", ) ) Example().run() .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/custom-list-item.png :align: center .. tabs:: .. tab:: Declarative KV style .. code-block:: python from kivy.lang import Builder from kivymd.app import MDApp from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.list import IRightBodyTouch KV = ''' OneLineAvatarIconListItem: text: "One-line item with avatar" on_size: self.ids._right_container.width = container.width self.ids._right_container.x = container.width IconLeftWidget: icon: "cog" YourContainer: id: container MDIconButton: icon: "minus" MDIconButton: icon: "plus" ''' class YourContainer(IRightBodyTouch, MDBoxLayout): adaptive_width = True class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return Builder.load_string(KV) Example().run() .. tab:: Declarative python style .. code-block:: python from kivymd.app import MDApp from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.list import IRightBodyTouch from kivymd.uix.button import MDIconButton from kivymd.uix.list import OneLineAvatarIconListItem, IconLeftWidget class YourContainer(IRightBodyTouch, MDBoxLayout): adaptive_width = True class Example(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return ( OneLineAvatarIconListItem( IconLeftWidget( icon="cog" ), YourContainer( MDIconButton( icon="minus" ), MDIconButton( icon="plus" ), id="container" ), text="One-line item with avatar" ) ) def on_start(self): container = self.root.ids.container self.root.ids._right_container.width = container.width container.x = container.width Example().run() .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/custom-list-right-container.png :align: center Behavior -------- When using the `AvatarListItem` and `IconListItem` classes, when an icon is clicked, the event of this icon is triggered: .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineIconListItem: text: "Single-line item with icon" IconLeftWidget: icon: "language-python" .. tab:: Declarative python style .. code-block:: python OneLineIconListItem( IconLeftWidget( icon="language-python" ), text="Single-line item with avatar", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/list-icon-trigger.gif :align: center You can disable the icon event using the `WithoutTouch` classes: .. tabs:: .. tab:: Declarative KV style .. code-block:: kv OneLineIconListItem: text: "Single-line item with icon" IconLeftWidgetWithoutTouch: icon: "language-python" .. tab:: Declarative python style .. code-block:: python OneLineIconListItem( IconLeftWidgetWithoutTouch( icon="language-python" ), text="Single-line item with avatar", ) .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/list-icon-without-trigger.gif :align: center """ __all__ = ( "BaseListItem", "MDList", "ILeftBodyTouch", "IRightBodyTouch", "OneLineListItem", "TwoLineListItem", "ThreeLineListItem", "OneLineAvatarListItem", "TwoLineAvatarListItem", "ThreeLineAvatarListItem", "OneLineIconListItem", "TwoLineIconListItem", "ThreeLineIconListItem", "OneLineRightIconListItem", "TwoLineRightIconListItem", "ThreeLineRightIconListItem", "OneLineAvatarIconListItem", "TwoLineAvatarIconListItem", "ThreeLineAvatarIconListItem", "ImageLeftWidget", "ImageRightWidget", "IconRightWidget", "IconLeftWidget", "CheckboxLeftWidget", "IconLeftWidgetWithoutTouch", "IconRightWidgetWithoutTouch", "ImageRightWidgetWithoutTouch", "ImageLeftWidgetWithoutTouch", ) import os from kivy.lang import Builder from kivy.metrics import dp from kivy.properties import ( BooleanProperty, ColorProperty, ListProperty, NumericProperty, OptionProperty, StringProperty, VariableListProperty, ) from kivy.uix.behaviors import ButtonBehavior from kivy.uix.floatlayout import FloatLayout import kivymd.material_resources as m_res from kivymd import uix_path from kivymd.theming import ThemableBehavior from kivymd.uix.behaviors import ( CircularRippleBehavior, DeclarativeBehavior, RectangularRippleBehavior, ) from kivymd.uix.button import MDIconButton from kivymd.uix.fitimage import FitImage from kivymd.uix.gridlayout import MDGridLayout from kivymd.uix.selectioncontrol import MDCheckbox with open( os.path.join(uix_path, "list", "list.kv"), encoding="utf-8" ) as kv_file: Builder.load_string(kv_file.read()) class MDList(MDGridLayout): """ ListItem container. Best used in conjunction with a :class:`kivy.uix.ScrollView`. When adding (or removing) a widget, it will resize itself to fit its children, plus top and bottom paddings as described by the `MD` spec. For more information, see in the :class:`~kivymd.uix.gridlayout.MDGridLayout` classes documentation. """ _list_vertical_padding = NumericProperty("8dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.adaptive_height = True class BaseListItem( DeclarativeBehavior, ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, FloatLayout, ): """ Base class to all ListItems. Not supposed to be instantiated on its own. For more information, see in the :class:`~kivymd.uix.behaviors.DeclarativeBehavior` and :class:`~kivymd.theming.ThemableBehavior` and :class:`~kivymd.uix.behaviors.RectangularRippleBehavior` and :class:`~kivy.uix.behaviors.ButtonBehavior` and :class:`~kivy.uix.floatlayout.FloatLayout` classes documentation. """ text = StringProperty() """ Text shown in the first line. :attr:`text` is a :class:`~kivy.properties.StringProperty` and defaults to `''`. """ text_color = ColorProperty(None) """ Text color in (r, g, b, a) or string format used if :attr:`~theme_text_color` is set to `'Custom'`. :attr:`text_color` is a :class:`~kivy.properties.ColorProperty` and defaults to `None`. """ font_style = StringProperty("Subtitle1") """ Text font style. See `font-definitions `_ for more information. :attr:`font_style` is a :class:`~kivy.properties.StringProperty` and defaults to `'Subtitle1'`. """ theme_text_color = StringProperty("Primary", allownone=True) """ The name of the color scheme for for the primary text. :attr:`theme_text_color` is a :class:`~kivy.properties.StringProperty` and defaults to `'Primary'`. """ secondary_text = StringProperty() """ Text shown in the second line. :attr:`secondary_text` is a :class:`~kivy.properties.StringProperty` and defaults to `''`. """ tertiary_text = StringProperty() """ The text is displayed on the third line. :attr:`tertiary_text` is a :class:`~kivy.properties.StringProperty` and defaults to `''`. """ secondary_text_color = ColorProperty(None) """ Text color in (r, g, b, a) or string format used for secondary text if :attr:`~secondary_theme_text_color` is set to `'Custom'`. :attr:`secondary_text_color` is a :class:`~kivy.properties.ColorProperty` and defaults to `None`. """ tertiary_text_color = ColorProperty(None) """ Text color in (r, g, b, a) or string format used for tertiary text if :attr:`~tertiary_theme_text_color` is set to 'Custom'. :attr:`tertiary_text_color` is a :class:`~kivy.properties.ColorProperty` and defaults to `None`. """ secondary_theme_text_color = StringProperty("Secondary", allownone=True) """ The name of the color scheme for for the secondary text. :attr:`secondary_theme_text_color` is a :class:`~kivy.properties.StringProperty` and defaults to `'Secondary'`. """ tertiary_theme_text_color = StringProperty("Secondary", allownone=True) """ The name of the color scheme for for the tertiary text. :attr:`tertiary_theme_text_color` is a :class:`~kivy.properties.StringProperty` and defaults to `'Secondary'`. """ secondary_font_style = StringProperty("Body1") """ Font style for secondary line. See `font-definitions `_ for more information. :attr:`secondary_font_style` is a :class:`~kivy.properties.StringProperty` and defaults to `'Body1'`. """ tertiary_font_style = StringProperty("Body1") """ Font style for tertiary line. See `font-definitions `_ for more information. :attr:`tertiary_font_style` is a :class:`~kivy.properties.StringProperty` and defaults to `'Body1'`. """ divider = OptionProperty( "Full", options=["Full", "Inset", None], allownone=True ) """ Divider mode. Available options are: `'Full'`, `'Inset'` and default to `'Full'`. :attr:`divider` is a :class:`~kivy.properties.OptionProperty` and defaults to `'Full'`. """ divider_color = ColorProperty(None) """ Divider color in (r, g, b, a) or string format. .. versionadded:: 1.0.0 :attr:`divider_color` is a :class:`~kivy.properties.ColorProperty` and defaults to `None`. """ bg_color = ColorProperty(None) """ Background color for list item in (r, g, b, a) or string format. :attr:`bg_color` is a :class:`~kivy.properties.ColorProperty` and defaults to `None`. """ radius = VariableListProperty([0], length=4) """ Canvas radius. .. code-block:: python # Top left corner slice. MDBoxLayout: md_bg_color: app.theme_cls.primary_color radius: [25, 0, 0, 0] :attr:`radius` is an :class:`~kivy.properties.VariableListProperty` and defaults to `[0, 0, 0, 0]`. """ _txt_left_pad = NumericProperty("16dp") _txt_top_pad = NumericProperty() _txt_bot_pad = NumericProperty() _txt_right_pad = NumericProperty(m_res.HORIZ_MARGINS) _num_lines = 3 _no_ripple_effect = BooleanProperty(False) _touchable_widgets = ListProperty() def on_touch_down(self, touch): if self.propagate_touch_to_touchable_widgets(touch, "down"): return super().on_touch_down(touch) def on_touch_move(self, touch, *args): if self.propagate_touch_to_touchable_widgets(touch, "move", *args): return super().on_touch_move(touch, *args) def on_touch_up(self, touch): if self.propagate_touch_to_touchable_widgets(touch, "up"): return super().on_touch_up(touch) def propagate_touch_to_touchable_widgets(self, touch, touch_event, *args): triggered = False for i in self._touchable_widgets: if i.collide_point(touch.x, touch.y): triggered = True if touch_event == "down": i.on_touch_down(touch) elif touch_event == "move": i.on_touch_move(touch, *args) elif touch_event == "up": i.on_touch_up(touch) return triggered def add_widget(self, widget): if issubclass(widget.__class__, ILeftBody): self.ids._left_container.add_widget(widget) elif issubclass(widget.__class__, ILeftBodyTouch): self.ids._left_container.add_widget(widget) self._touchable_widgets.append(widget) elif issubclass(widget.__class__, IRightBody): self.ids._right_container.add_widget(widget) elif issubclass(widget.__class__, IRightBodyTouch): self.ids._right_container.add_widget(widget) self._touchable_widgets.append(widget) else: return super().add_widget(widget) def remove_widget(self, widget): super().remove_widget(widget) if widget in self._touchable_widgets: self._touchable_widgets.remove(widget) class ILeftBody: """ Pseudo-interface for widgets that go in the left container for ListItems that support it. Implements nothing and requires no implementation, for annotation only. """ class ILeftBodyTouch: """ Same as :class:`~ILeftBody`, but allows the widget to receive touch events instead of triggering the ListItem's ripple effect. """ class IRightBody: """ Pseudo-interface for widgets that go in the right container for ListItems that support it. Implements nothing and requires no implementation, for annotation only. """ class IRightBodyTouch: """ Same as :class:`~IRightBody`, but allows the widget to receive touch events instead of triggering the ``ListItem``'s ripple effect """ class OneLineListItem(BaseListItem): """ A one line list item. For more information, see in the :class:`~BaseListItem` classes documentation. """ _txt_top_pad = NumericProperty("16dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() _num_lines = 1 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.height = dp(48) if not self._height else self._height class TwoLineListItem(BaseListItem): """ A two line list item. For more information, see in the :class:`~BaseListItem` classes documentation. """ _txt_top_pad = NumericProperty("20dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() def __init__(self, **kwargs): super().__init__(**kwargs) self.height = dp(72) if not self._height else self._height class ThreeLineListItem(BaseListItem): """ A three line list item. For more information, see in the :class:`~BaseListItem` classes documentation. """ _txt_top_pad = NumericProperty("16dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() _num_lines = 3 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.height = dp(88) if not self._height else self._height class OneLineAvatarListItem(BaseListItem): """ A one line list item with left image. For more information, see in the :class:`~BaseListItem` classes documentation. """ _txt_left_pad = NumericProperty("72dp") _txt_top_pad = NumericProperty("20dp") _txt_bot_pad = NumericProperty("19dp") _height = NumericProperty() _num_lines = 1 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.height = dp(56) if not self._height else self._height class TwoLineAvatarListItem(OneLineAvatarListItem): """ A two line list item with left image. For more information, see in the :class:`~OneLineAvatarListItem` classes documentation. """ _txt_top_pad = NumericProperty("20dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() _num_lines = 2 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.height = dp(72) if not self._height else self._height class ThreeLineAvatarListItem(ThreeLineListItem): """ A three line list item with left image. For more information, see in the :class:`~ThreeLineListItem` classes documentation. """ _txt_left_pad = NumericProperty("72dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) class OneLineIconListItem(OneLineListItem): """ A one line list item with left icon. For more information, see in the :class:`~OneLineListItem` classes documentation. """ _txt_left_pad = NumericProperty("72dp") class TwoLineIconListItem(OneLineIconListItem): """ A two line list item with left icon. For more information, see in the :class:`~OneLineIconListItem` classes documentation. """ _txt_top_pad = NumericProperty("20dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() _num_lines = 2 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.height = dp(72) if not self._height else self._height class ThreeLineIconListItem(ThreeLineListItem): """ A three line list item with left icon. For more information, see in the :class:`~ThreeLineListItem` classes documentation. """ _txt_left_pad = NumericProperty("72dp") class OneLineRightIconListItem(OneLineListItem): """ A one line list item with right icon/image. For more information, see in the :class:`~OneLineListItem` classes documentation. """ _txt_right_pad = NumericProperty("40dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS class TwoLineRightIconListItem(OneLineRightIconListItem): """ A two line list item with right icon/image. For more information, see in the :class:`~OneLineRightIconListItem` classes documentation. """ _txt_top_pad = NumericProperty("20dp") _txt_bot_pad = NumericProperty("15dp") _height = NumericProperty() _num_lines = 2 def __init__(self, **kwargs): super().__init__(**kwargs) self.height = dp(72) if not self._height else self._height class ThreeLineRightIconListItem(ThreeLineListItem): """ A three line list item with right icon/image. For more information, see in the :class:`~ThreeLineRightIconListItem` classes documentation. """ _txt_right_pad = NumericProperty("40dp") def __init__(self, **kwargs): super().__init__(**kwargs) self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS class OneLineAvatarIconListItem(OneLineAvatarListItem): """ A one line list item with left/right icon/image/widget. For more information, see in the :class:`~OneLineAvatarListItem` classes documentation. """ _txt_right_pad = NumericProperty("40dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS class TwoLineAvatarIconListItem(TwoLineAvatarListItem): """ A two line list item with left/right icon/image/widget. For more information, see in the :class:`~TwoLineAvatarListItem` classes documentation. """ _txt_right_pad = NumericProperty("40dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS class ThreeLineAvatarIconListItem(ThreeLineAvatarListItem): """ A three line list item with left/right icon/image/widget. For more information, see in the :class:`~ThreeLineAvatarListItem` classes documentation. """ _txt_right_pad = NumericProperty("40dp") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS class TouchBehavior: def on_release(self): if issubclass(self.parent.parent.__class__, BaseListItem): self.parent.parent.dispatch("on_release") class ImageLeftWidget( CircularRippleBehavior, ButtonBehavior, ILeftBodyTouch, FitImage ): """ The widget implements the left image for use in ListItem classes. For more information, see in the :class:`~kivymd.uix.behaviors.CircularRippleBehavior` and :class:`~kivy.uix.behaviors.ButtonBehavior` and :class:`~ILeftBodyTouch` and :class:`~kivymd.uix.fitimage.FitImage` classes documentation. """ class ImageLeftWidgetWithoutTouch( CircularRippleBehavior, TouchBehavior, ButtonBehavior, ILeftBody, FitImage ): """ Disables the image event. The widget implements the left image for use in `ListItem` classes. For more information, see in the :class:`~kivymd.uix.behaviors.CircularRippleBehavior` and :class:`~TouchBehavior` and :class:`~kivy.uix.behaviors.ButtonBehavior` and :class:`~ILeftBody` and :class:`~kivymd.uix.fitimage.FitImage` classes documentation. .. versionadded:: 1.0.0 """ _no_ripple_effect = True class ImageRightWidget( CircularRippleBehavior, ButtonBehavior, IRightBodyTouch, FitImage ): """ The widget implements the right image for use in ListItem classes. For more information, see in the :class:`~kivymd.uix.behaviors.CircularRippleBehavior` and :class:`~kivy.uix.behaviors.ButtonBehavior` and :class:`~IRightBodyTouch` and :class:`~kivymd.uix.fitimage.FitImage` classes documentation. """ class ImageRightWidgetWithoutTouch( CircularRippleBehavior, TouchBehavior, ButtonBehavior, IRightBody, FitImage ): """ Disables the image event. The widget implements the right image for use in `ListItem` classes. For more information, see in the :class:`~kivymd.uix.behaviors.CircularRippleBehavior` and :class:`~TouchBehavior` and :class:`~kivy.uix.behaviors.ButtonBehavior` and :class:`~IRightBody` and :class:`~kivymd.uix.fitimage.FitImage` classes documentation. .. versionadded:: 1.0.0 """ _no_ripple_effect = True class IconRightWidget(IRightBodyTouch, MDIconButton): """ The widget implements the right icon for use in ListItem classes. For more information, see in the :class:`~IRightBodyTouch` and :class:`~kivymd.uix.button.MDIconButton` classes documentation. """ pos_hint = {"center_y": 0.5} class IconRightWidgetWithoutTouch(TouchBehavior, IRightBody, MDIconButton): """ Disables the icon event. The widget implements the right icon for use in ListItem classes. For more information, see in the :class:`~TouchBehavior` and :class:`~IRightBody` and :class:`~kivymd.uix.button.MDIconButton` classes documentation. .. versionadded:: 1.0.0 """ pos_hint = {"center_y": 0.5} _no_ripple_effect = True class IconLeftWidget(ILeftBodyTouch, MDIconButton): """ The widget implements the left icon for use in ListItem classes. For more information, see in the :class:`~ILeftBodyTouch` and :class:`~kivymd.uix.button.MDIconButton` classes documentation. """ pos_hint = {"center_y": 0.5} class IconLeftWidgetWithoutTouch(TouchBehavior, ILeftBody, MDIconButton): """ Disables the icon event. The widget implements the left icon for use in ListItem classes. For more information, see in the :class:`~TouchBehavior` and :class:`~ILeftBody` and :class:`~kivymd.uix.button.MDIconButton` classes documentation. .. versionadded:: 1.0.0 """ pos_hint = {"center_y": 0.5} _no_ripple_effect = True class CheckboxLeftWidget(ILeftBodyTouch, MDCheckbox): """ The widget implements the left checkbox element for use in ListItem classes. For more information, see in the :class:`~ILeftBodyTouch` and :class:`~kivymd.uix.selectioncontrol.MDCheckbox` classes documentation. """