openCom-Companion/sbapp/kivymd/uix/imagelist/imagelist.py
2023-07-10 02:49:58 +02:00

280 lines
7.8 KiB
Python

"""
Components/ImageList
====================
.. seealso::
`Material Design spec, Image lists <https://material.io/components/image-lists>`_
.. rubric:: Image lists display a collection of images in an organized grid.
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/image-list.png
:align: center
`KivyMD` provides the following tile classes for use:
Usage
-----
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
MDSmartTile:
radius: 24
box_radius: [0, 0, 24, 24]
box_color: 1, 1, 1, .2
source: "cats.jpg"
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: None, None
size: "320dp", "320dp"
MDIconButton:
icon: "heart-outline"
theme_icon_color: "Custom"
icon_color: 1, 0, 0, 1
pos_hint: {"center_y": .5}
on_release: self.icon = "heart" if self.icon == "heart-outline" else "heart-outline"
MDLabel:
text: "Julia and Julie"
bold: True
color: 1, 1, 1, 1
'''
class MyApp(MDApp):
def build(self):
return Builder.load_string(KV)
MyApp().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-usage.gif
:align: center
Implementation
--------------
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-usage-sceleton.png
:align: center
"""
__all__ = [
"MDSmartTile",
]
import os
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import (
BooleanProperty,
ColorProperty,
OptionProperty,
StringProperty,
VariableListProperty,
)
from kivy.uix.behaviors import ButtonBehavior
from kivymd import uix_path
from kivymd.uix.behaviors import RectangularRippleBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.fitimage import FitImage
from kivymd.uix.label import MDLabel
from kivymd.uix.relativelayout import MDRelativeLayout
with open(
os.path.join(uix_path, "imagelist", "imagelist.kv"), encoding="utf-8"
) as kv_file:
Builder.load_string(kv_file.read())
class SmartTileImage(RectangularRippleBehavior, ButtonBehavior, FitImage):
"""Implements the tile image."""
class SmartTileOverlayBox(MDBoxLayout):
"""Implements a container for custom widgets to be added to the tile."""
class MDSmartTile(MDRelativeLayout):
"""
A tile for more complex needs.
For more information, see in the
:class:`~kivymd.uix.relativelayout.MDRelativeLayout` class documentation.
Includes an image, a container to place overlays and a box that can act
as a header or a footer, as described in the Material Design specs.
:Events:
`on_press`
Called when the button is pressed.
`on_release`
Called when the button is released (i.e. the touch/click that
pressed the button goes away).
"""
box_radius = VariableListProperty([0], length=4)
"""
Box radius.
.. versionadded:: 1.0.0
.. code-block:: kv
MDSmartTile:
radius: 24
box_radius: [0, 0, 24, 24]
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-box-radius.png
:align: center
:attr:`box_radius` is an :class:`~kivy.properties.VariableListProperty`
and defaults to `[0, 0, 0, 0]`.
"""
box_color = ColorProperty((0, 0, 0, 0.5))
"""
Sets the color in (r, g, b, a) or string format and opacity for the
information box.
.. code-block:: kv
MDSmartTile:
radius: 24
box_radius: [0, 0, 24, 24]
box_color: 0, 1, 0, .5
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-box-color.png
:align: center
:attr:`box_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `(0, 0, 0, 0.5)`.
"""
box_position = OptionProperty("footer", options=["footer", "header"])
"""
Determines weather the information box acts as a header or footer to the
image. Available are options: `'footer'`, `'header'`.
.. code-block:: kv
MDSmartTile:
radius: 24
box_radius: [24, 24, 0, 0]
box_position: "header"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-box-position.png
:align: center
:attr:`box_position` is a :class:`~kivy.properties.OptionProperty`
and defaults to `'footer'`.
"""
overlap = BooleanProperty(True)
"""
Determines if the `header/footer` overlaps on top of the image or not.
.. code-block:: kv
MDSmartTile:
radius: [24, 24, 0, 0]
box_radius: [0, 0, 24, 24]
overlap: False
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-overlap.png
:align: center
:attr:`overlap` is a :class:`~kivy.properties.BooleanProperty`
and defaults to `True`.
"""
lines = OptionProperty(1, options=[1, 2])
"""
Number of lines in the `header/footer`. As per `Material Design specs`,
only 1 and 2 are valid values. Available are options: `1`, `2`.
This parameter just increases the height of the container for custom
elements.
.. code-block:: kv
MDSmartTile:
radius: 24
box_radius: [0, 0, 24, 24]
lines: 2
source: "cats.jpg"
pos_hint: {"center_x": .5, "center_y": .5}
size_hint: None, None
size: "320dp", "320dp"
MDIconButton:
icon: "heart-outline"
theme_icon_color: "Custom"
icon_color: 1, 0, 0, 1
pos_hint: {"center_y": .5}
on_release: self.icon = "heart" if self.icon == "heart-outline" else "heart-outline"
TwoLineListItem:
text: "[color=#ffffff][b]My cats[/b][/color]"
secondary_text: "[color=#808080][b]Julia and Julie[/b][/color]"
pos_hint: {"center_y": .5}
_no_ripple_effect: True
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-smart-tile-lines.png
:align: center
:attr:`lines` is a :class:`~kivy.properties.OptionProperty`
and defaults to `1`.
"""
source = StringProperty()
"""
Path to tile image. See :attr:`~kivy.uix.image.Image.source`.
:attr:`source` is a :class:`~kivy.properties.StringProperty`
and defaults to `''`.
"""
mipmap = BooleanProperty(False)
"""
Indicate if you want OpenGL mipmapping to be applied to the texture.
Read :ref:`mipmap` for more information.
.. versionadded:: 1.0.0
:attr:`mipmap` is a :class:`~kivy.properties.BooleanProperty`
and defaults to `False`.
"""
_no_ripple_effect = BooleanProperty(False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.register_event_type("on_release")
self.register_event_type("on_press")
def on_release(self, *args):
"""
Called when the button is released (i.e. the touch/click that
pressed the button goes away).
"""
def on_press(self, *args):
"""Called when the button is pressed."""
def add_widget(self, widget, *args, **kwargs):
if isinstance(widget, (SmartTileImage, SmartTileOverlayBox)):
return super().add_widget(widget, *args, **kwargs)
else:
if isinstance(widget, MDLabel):
widget.shorten = True
widget.shorten_from = "right"
Clock.schedule_once(lambda x: self.ids.box.add_widget(widget))