Sideband_CE/sbapp/kivymd/uix/list/list.py

1448 lines
39 KiB
Python
Raw Normal View History

2022-07-07 22:16:10 +02:00
"""
Components/List
===============
.. seealso::
`Material Design spec, Lists <https://material.io/components/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_
2022-10-02 17:16:59 +02:00
2022-07-07 22:16:10 +02:00
- OneLineIconListItem_
- TwoLineIconListItem_
- ThreeLineIconListItem_
.. rubric:: It allows the use of elements with custom widgets on the left
and the right.
- OneLineAvatarIconListItem_
- TwoLineAvatarIconListItem_
- ThreeLineAvatarIconListItem_
2022-10-02 17:16:59 +02:00
- OneLineRightIconListItem_
- TwoLineRightIconListItem_
- ThreeLineRightIconListItem_
2022-07-07 22:16:10 +02:00
Usage
-----
2022-10-02 17:16:59 +02:00
.. 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)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
def on_start(self):
for i in range(20):
self.root.ids.container.add_widget(
OneLineListItem(text=f"Single-line item {i}")
)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
Example().run()
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
from kivymd.app import MDApp
from kivymd.uix.list import OneLineListItem
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class Example(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
return (
MDScrollView(
MDList(
id="container"
)
)
)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
def on_start(self):
for i in range(20):
self.root.ids.container.add_widget(
OneLineListItem(text=f"Single-line item {i}")
)
Example().run()
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/lists.gif
:align: center
Events of List
--------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative KV style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
from kivy.lang import Builder
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
from kivymd.app import MDApp
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
KV = '''
MDScrollView:
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
MDList:
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
OneLineAvatarIconListItem:
on_release: print("Click!")
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
Example().run()
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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()
2022-07-07 22:16:10 +02:00
.. 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
---------------------
2022-10-02 17:16:59 +02:00
.. tabs::
.. tab:: Declarative KV style
.. code-block:: kv
OneLineAvatarListItem:
text: "Single-line item with avatar"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
ImageLeftWidget:
source: "kivymd/images/logo/kivymd-icon-256.png"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
:align: center
.. TwoLineAvatarListItem:
TwoLineAvatarListItem
---------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
OneLineAvatarListItem(
ImageLeftWidget(
source="kivymd/images/logo/kivymd-icon-256.png"
),
text="Single-line item with avatar",
secondary_text: "Secondary text here",
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineAvatarListItem.png
:align: center
.. ThreeLineAvatarListItem:
ThreeLineAvatarListItem
-----------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative KV style
.. code-block:: kv
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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"
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineAvatarListItem.png
:align: center
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
.. OneLineIconListItem:
OneLineIconListItem
-------------------
2022-10-02 17:16:59 +02:00
.. tabs::
.. tab:: Declarative KV style
.. code-block:: kv
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
OneLineIconListItem:
text: "Single-line item with avatar"
IconLeftWidget:
icon: "language-python"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
.. code-block:: python
OneLineIconListItem(
IconLeftWidget(
icon="language-python"
),
text="Single-line item with avatar"
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineIconListItem.png
:align: center
.. TwoLineIconListItem:
TwoLineIconListItem
-------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
TwoLineIconListItem(
IconLeftWidget(
icon="language-python"
),
text="Single-line item with avatar",
secondary_text: "Secondary text here"
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineIconListItem.png
:align: center
.. ThreeLineIconListItem:
ThreeLineIconListItem
---------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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",
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineIconListItem.png
:align: center
.. OneLineAvatarIconListItem:
OneLineAvatarIconListItem
-------------------------
2022-10-02 17:16:59 +02:00
.. tabs::
.. tab:: Declarative KV style
.. code-block:: kv
OneLineAvatarIconListItem:
text: "One-line item with avatar"
IconLeftWidget:
icon: "plus"
IconRightWidget:
icon: "minus"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
OneLineAvatarIconListItem(
IconLeftWidget(
icon="plus"
),
IconRightWidget(
icon="minus"
),
text="Single-line item with avatar",
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/OneLineAvatarIconListItem.png
:align: center
.. TwoLineAvatarIconListItem:
TwoLineAvatarIconListItem
-------------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
TwoLineAvatarIconListItem(
IconLeftWidget(
icon="plus"
),
IconRightWidget(
icon="minus"
),
text="Single-line item with avatar",
secondary_text: "Secondary text here",
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/TwoLineAvatarIconListItem.png
:align: center
.. ThreeLineAvatarIconListItem:
ThreeLineAvatarIconListItem
---------------------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
IconRightWidget:
icon: "minus"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. 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",
)
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ThreeLineAvatarIconListItem.png
:align: center
Custom list item
----------------
2022-10-02 17:16:59 +02:00
.. tabs::
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative KV style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
from kivy.lang import Builder
from kivy.properties import StringProperty
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
KV = '''
<ListItemWithCheckbox>:
IconLeftWidget:
icon: root.icon
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
RightCheckbox:
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
MDScrollView:
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
MDList:
id: scroll
'''
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class ListItemWithCheckbox(OneLineAvatarIconListItem):
'''Custom list item.'''
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
icon = StringProperty("android")
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class RightCheckbox(IRightBodyTouch, MDCheckbox):
'''Custom right container.'''
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class Example(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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])
)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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()
2022-07-07 22:16:10 +02:00
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/custom-list-item.png
:align: center
2022-10-02 17:16:59 +02:00
.. 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"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
YourContainer:
id: container
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
MDIconButton:
icon: "minus"
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
MDIconButton:
icon: "plus"
'''
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class YourContainer(IRightBodyTouch, MDBoxLayout):
adaptive_width = True
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class Example(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
Example().run()
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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()
2022-07-07 22:16:10 +02:00
.. 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:
2022-10-02 17:16:59 +02:00
.. tabs::
.. tab:: Declarative KV style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: kv
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
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",
)
2022-07-07 22:16:10 +02:00
.. 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:
2022-10-02 17:16:59 +02:00
.. tabs::
.. tab:: Declarative KV style
.. code-block:: kv
OneLineIconListItem:
text: "Single-line item with icon"
IconLeftWidgetWithoutTouch:
icon: "language-python"
.. tab:: Declarative python style
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
.. code-block:: python
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
OneLineIconListItem(
IconLeftWidgetWithoutTouch(
icon="language-python"
),
text="Single-line item with avatar",
)
2022-07-07 22:16:10 +02:00
.. 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,
2022-10-02 17:16:59 +02:00
VariableListProperty,
2022-07-07 22:16:10 +02:00
)
from kivy.uix.behaviors import ButtonBehavior
2022-10-02 17:16:59 +02:00
from kivy.uix.floatlayout import FloatLayout
2022-07-07 22:16:10 +02:00
import kivymd.material_resources as m_res
from kivymd import uix_path
from kivymd.theming import ThemableBehavior
from kivymd.uix.behaviors import (
CircularRippleBehavior,
2022-10-02 17:16:59 +02:00
DeclarativeBehavior,
2022-07-07 22:16:10 +02:00
RectangularRippleBehavior,
)
from kivymd.uix.button import MDIconButton
2022-10-02 17:16:59 +02:00
from kivymd.uix.fitimage import FitImage
2022-07-07 22:16:10 +02:00
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.
"""
_list_vertical_padding = NumericProperty("8dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.adaptive_height = True
2022-07-07 22:16:10 +02:00
class BaseListItem(
2022-10-02 17:16:59 +02:00
DeclarativeBehavior,
ThemableBehavior,
RectangularRippleBehavior,
ButtonBehavior,
FloatLayout,
2022-07-07 22:16:10 +02:00
):
"""
Base class to all ListItems. Not supposed to be instantiated on its own.
"""
text = StringProperty()
"""
Text shown in the first line.
:attr:`text` is a :class:`~kivy.properties.StringProperty`
and defaults to `''`.
"""
text_color = ColorProperty(None)
"""
2022-10-02 17:16:59 +02:00
Text color in (r, g, b, a) or string format used
if :attr:`~theme_text_color` is set to `'Custom'`.
2022-07-07 22:16:10 +02:00
:attr:`text_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
font_style = StringProperty("Subtitle1")
"""
2022-10-02 17:16:59 +02:00
Text font style.
See `font-definitions <https://kivymd.readthedocs.io/en/latest/themes/font-definitions/>`_
for more information.
2022-07-07 22:16:10 +02:00
:attr:`font_style` is a :class:`~kivy.properties.StringProperty`
and defaults to `'Subtitle1'`.
"""
theme_text_color = StringProperty("Primary", allownone=True)
"""
2022-10-02 17:16:59 +02:00
The name of the color scheme for for the primary text.
2022-07-07 22:16:10 +02:00
: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)
"""
2022-10-02 17:16:59 +02:00
Text color in (r, g, b, a) or string format used for secondary text
2022-07-07 22:16:10 +02:00
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)
"""
2022-10-02 17:16:59 +02:00
Text color in (r, g, b, a) or string format used for tertiary text
2022-07-07 22:16:10 +02:00
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)
"""
2022-10-02 17:16:59 +02:00
The name of the color scheme for for the secondary text.
2022-07-07 22:16:10 +02:00
:attr:`secondary_theme_text_color` is a :class:`~kivy.properties.StringProperty`
and defaults to `'Secondary'`.
"""
tertiary_theme_text_color = StringProperty("Secondary", allownone=True)
"""
2022-10-02 17:16:59 +02:00
The name of the color scheme for for the tertiary text.
2022-07-07 22:16:10 +02:00
:attr:`tertiary_theme_text_color` is a :class:`~kivy.properties.StringProperty`
and defaults to `'Secondary'`.
"""
secondary_font_style = StringProperty("Body1")
"""
2022-10-02 17:16:59 +02:00
Font style for secondary line.
See `font-definitions <https://kivymd.readthedocs.io/en/latest/themes/font-definitions/>`_
for more information.
2022-07-07 22:16:10 +02:00
:attr:`secondary_font_style` is a :class:`~kivy.properties.StringProperty`
and defaults to `'Body1'`.
"""
tertiary_font_style = StringProperty("Body1")
"""
2022-10-02 17:16:59 +02:00
Font style for tertiary line.
See `font-definitions <https://kivymd.readthedocs.io/en/latest/themes/font-definitions/>`_
for more information.
2022-07-07 22:16:10 +02:00
: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)
"""
2022-10-02 17:16:59 +02:00
Divider color in (r, g, b, a) or string format.
2022-07-07 22:16:10 +02:00
.. versionadded:: 1.0.0
:attr:`divider_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
bg_color = ColorProperty(None)
"""
2022-10-02 17:16:59 +02:00
Background color for list item in (r, g, b, a) or string format.
2022-07-07 22:16:10 +02:00
:attr:`bg_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
2022-10-02 17:16:59 +02:00
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]`.
"""
2022-07-07 22:16:10 +02:00
_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)
2022-10-02 17:16:59 +02:00
_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)
2022-07-07 22:16:10 +02:00
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."""
_txt_top_pad = NumericProperty("16dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 1
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self.height = dp(48) if not self._height else self._height
class TwoLineListItem(BaseListItem):
"""A two line list item."""
_txt_top_pad = NumericProperty("20dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_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."""
_txt_top_pad = NumericProperty("16dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 3
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self.height = dp(88) if not self._height else self._height
2022-10-02 17:16:59 +02:00
class OneLineAvatarListItem(BaseListItem):
2022-07-07 22:16:10 +02:00
_txt_left_pad = NumericProperty("72dp")
_txt_top_pad = NumericProperty("20dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("19dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 1
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self.height = dp(56) if not self._height else self._height
class TwoLineAvatarListItem(OneLineAvatarListItem):
_txt_top_pad = NumericProperty("20dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 2
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self.height = dp(72) if not self._height else self._height
2022-10-02 17:16:59 +02:00
class ThreeLineAvatarListItem(ThreeLineListItem):
2022-07-07 22:16:10 +02:00
_txt_left_pad = NumericProperty("72dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
2022-10-02 17:16:59 +02:00
class OneLineIconListItem(OneLineListItem):
2022-07-07 22:16:10 +02:00
_txt_left_pad = NumericProperty("72dp")
class TwoLineIconListItem(OneLineIconListItem):
_txt_top_pad = NumericProperty("20dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 2
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self.height = dp(72) if not self._height else self._height
2022-10-02 17:16:59 +02:00
class ThreeLineIconListItem(ThreeLineListItem):
2022-07-07 22:16:10 +02:00
_txt_left_pad = NumericProperty("72dp")
2022-10-02 17:16:59 +02:00
class OneLineRightIconListItem(OneLineListItem):
2022-07-07 22:16:10 +02:00
_txt_right_pad = NumericProperty("40dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS
class TwoLineRightIconListItem(OneLineRightIconListItem):
_txt_top_pad = NumericProperty("20dp")
2022-10-02 17:16:59 +02:00
_txt_bot_pad = NumericProperty("15dp")
2022-07-07 22:16:10 +02:00
_height = NumericProperty()
_num_lines = 2
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.height = dp(72) if not self._height else self._height
2022-10-02 17:16:59 +02:00
class ThreeLineRightIconListItem(ThreeLineListItem):
2022-07-07 22:16:10 +02:00
_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):
_txt_right_pad = NumericProperty("40dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS
class TwoLineAvatarIconListItem(TwoLineAvatarListItem):
_txt_right_pad = NumericProperty("40dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
self._txt_right_pad = dp(40) + m_res.HORIZ_MARGINS
class ThreeLineAvatarIconListItem(ThreeLineAvatarListItem):
_txt_right_pad = NumericProperty("40dp")
2022-10-02 17:16:59 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
2022-07-07 22:16:10 +02:00
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
):
pass
class ImageLeftWidgetWithoutTouch(
CircularRippleBehavior, TouchBehavior, ButtonBehavior, ILeftBody, FitImage
):
"""
.. versionadded:: 1.0.0
"""
_no_ripple_effect = True
class ImageRightWidget(
CircularRippleBehavior, ButtonBehavior, IRightBodyTouch, FitImage
):
pass
class ImageRightWidgetWithoutTouch(
CircularRippleBehavior, TouchBehavior, ButtonBehavior, IRightBody, FitImage
):
"""
.. versionadded:: 1.0.0
"""
_no_ripple_effect = True
class IconRightWidget(IRightBodyTouch, MDIconButton):
pos_hint = {"center_y": 0.5}
class IconRightWidgetWithoutTouch(TouchBehavior, IRightBody, MDIconButton):
"""
.. versionadded:: 1.0.0
"""
pos_hint = {"center_y": 0.5}
_no_ripple_effect = True
class IconLeftWidget(ILeftBodyTouch, MDIconButton):
pos_hint = {"center_y": 0.5}
class IconLeftWidgetWithoutTouch(TouchBehavior, ILeftBody, MDIconButton):
"""
.. versionadded:: 1.0.0
"""
pos_hint = {"center_y": 0.5}
_no_ripple_effect = True
class CheckboxLeftWidget(ILeftBodyTouch, MDCheckbox):
pass