584 lines
15 KiB
Python
Executable File
584 lines
15 KiB
Python
Executable File
"""
|
|
Components/Chip
|
|
===============
|
|
|
|
.. seealso::
|
|
|
|
`Material Design spec, Chips <https://material.io/components/chips>`_
|
|
|
|
.. rubric:: Chips are compact elements that represent an input, attribute, or action.
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chips.png
|
|
:align: center
|
|
|
|
Usage
|
|
-----
|
|
|
|
.. code-block:: python
|
|
|
|
from kivy.lang import Builder
|
|
|
|
from kivymd.app import MDApp
|
|
|
|
KV = '''
|
|
MDScreen:
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
pos_hint: {"center_x": .5, "center_y": .5}
|
|
on_release: app.on_release_chip(self)
|
|
'''
|
|
|
|
|
|
class Test(MDApp):
|
|
def build(self):
|
|
return Builder.load_string(KV)
|
|
|
|
def on_release_chip(self, instance_check):
|
|
print(instance_check)
|
|
|
|
|
|
Test().run()
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/ordinary-chip.png
|
|
:align: center
|
|
|
|
Use with right icon
|
|
-------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_right: "close-circle-outline"
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-right-icon.png
|
|
:align: center
|
|
|
|
Use with left icon
|
|
------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "map-marker"
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-left-icon.png
|
|
:align: center
|
|
|
|
Use with custom left icon
|
|
-------------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "avatar.png"
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-custom-left-icon.png
|
|
:align: center
|
|
|
|
Use with left and right icon
|
|
----------------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "avatar.png"
|
|
icon_right: "close-circle-outline"
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-left-right-icon.png
|
|
:align: center
|
|
|
|
Use with outline
|
|
----------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "avatar.png"
|
|
icon_right: "close-circle-outline"
|
|
line_color: app.theme_cls.disabled_hint_text_color
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-outline.png
|
|
:align: center
|
|
|
|
Use with custom color
|
|
---------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "avatar.png"
|
|
icon_right: "close-circle-outline"
|
|
line_color: app.theme_cls.disabled_hint_text_color
|
|
md_bg_color: 1, 0, 0, .5
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-custom-color.png
|
|
:align: center
|
|
|
|
Use with elevation
|
|
------------------
|
|
|
|
.. code-block:: kv
|
|
|
|
MDChip:
|
|
text: "Portland"
|
|
icon_left: "avatar.png"
|
|
icon_right: "close-circle-outline"
|
|
line_color: app.theme_cls.disabled_hint_text_color
|
|
md_bg_color: 1, 0, 0, .5
|
|
elevation: 12
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-elevation.png
|
|
:align: center
|
|
|
|
Behavior
|
|
========
|
|
|
|
Long press on the chip, it will be marked.
|
|
When you click on the marked chip, the mark will be removed:
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-activate.gif
|
|
:align: center
|
|
|
|
Examples
|
|
========
|
|
|
|
Multiple choose
|
|
---------------
|
|
|
|
Selecting a single choice chip automatically deselects all other chips in the set.
|
|
|
|
.. code-block:: python
|
|
|
|
from kivy.animation import Animation
|
|
from kivy.lang import Builder
|
|
|
|
from kivymd.uix.screen import MDScreen
|
|
from kivymd.uix.chip import MDChip
|
|
from kivymd.app import MDApp
|
|
|
|
KV = '''
|
|
<MyScreen>
|
|
|
|
MDBoxLayout:
|
|
orientation: "vertical"
|
|
adaptive_size: True
|
|
spacing: "12dp"
|
|
padding: "56dp"
|
|
pos_hint: {"center_x": .5, "center_y": .5}
|
|
|
|
MDLabel:
|
|
text: "Multiple choice"
|
|
bold: True
|
|
font_style: "H5"
|
|
adaptive_size: True
|
|
|
|
MDBoxLayout:
|
|
id: chip_box
|
|
adaptive_size: True
|
|
spacing: "8dp"
|
|
|
|
MyChip:
|
|
text: "Elevator"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
MyChip:
|
|
text: "Washer / Dryer"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
MyChip:
|
|
text: "Fireplace"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
|
|
ScreenManager:
|
|
|
|
MyScreen:
|
|
'''
|
|
|
|
|
|
class MyChip(MDChip):
|
|
icon_check_color = (0, 0, 0, 1)
|
|
text_color = (0, 0, 0, 0.5)
|
|
_no_ripple_effect = True
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
self.bind(active=self.set_chip_bg_color)
|
|
self.bind(active=self.set_chip_text_color)
|
|
|
|
def set_chip_bg_color(self, instance_chip, active_value: int):
|
|
'''
|
|
Will be called every time the chip is activated/deactivated.
|
|
Sets the background color of the chip.
|
|
'''
|
|
|
|
self.md_bg_color = (
|
|
(0, 0, 0, 0.4)
|
|
if active_value
|
|
else (
|
|
self.theme_cls.bg_darkest
|
|
if self.theme_cls.theme_style == "Light"
|
|
else (
|
|
self.theme_cls.bg_light
|
|
if not self.disabled
|
|
else self.theme_cls.disabled_hint_text_color
|
|
)
|
|
)
|
|
)
|
|
|
|
def set_chip_text_color(self, instance_chip, active_value: int):
|
|
Animation(
|
|
color=(0, 0, 0, 1) if active_value else (0, 0, 0, 0.5), d=0.2
|
|
).start(self.ids.label)
|
|
|
|
|
|
class MyScreen(MDScreen):
|
|
def removes_marks_all_chips(self):
|
|
for instance_chip in self.ids.chip_box.children:
|
|
if instance_chip.active:
|
|
instance_chip.active = False
|
|
|
|
|
|
class Test(MDApp):
|
|
def build(self):
|
|
return Builder.load_string(KV)
|
|
|
|
|
|
Test().run()
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-multiple-choose.gif
|
|
:align: center
|
|
|
|
Only choose
|
|
-----------
|
|
|
|
Only one chip will be selected.
|
|
|
|
.. code-block:: python
|
|
|
|
KV = '''
|
|
<MyScreen>
|
|
|
|
[...]
|
|
|
|
MDBoxLayout:
|
|
id: chip_box
|
|
adaptive_size: True
|
|
spacing: "8dp"
|
|
|
|
MyChip:
|
|
text: "Elevator"
|
|
on_active: if self.active: root.removes_marks_all_chips(self)
|
|
|
|
MyChip:
|
|
text: "Washer / Dryer"
|
|
on_active: if self.active: root.removes_marks_all_chips(self)
|
|
|
|
MyChip:
|
|
text: "Fireplace"
|
|
on_active: if self.active: root.removes_marks_all_chips(self)
|
|
|
|
|
|
[...]
|
|
'''
|
|
|
|
|
|
class MyScreen(MDScreen):
|
|
def removes_marks_all_chips(self, selected_instance_chip):
|
|
for instance_chip in self.ids.chip_box.children:
|
|
if instance_chip != selected_instance_chip:
|
|
instance_chip.active = False
|
|
|
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-only-choose.gif
|
|
:align: center
|
|
"""
|
|
|
|
__all__ = ("MDChip",)
|
|
|
|
import os
|
|
|
|
from kivy import Logger
|
|
from kivy.animation import Animation
|
|
from kivy.lang import Builder
|
|
from kivy.metrics import dp
|
|
from kivy.properties import BooleanProperty, ColorProperty, StringProperty
|
|
from kivy.uix.behaviors import ButtonBehavior
|
|
|
|
from kivymd import uix_path
|
|
from kivymd.theming import ThemableBehavior
|
|
from kivymd.uix.behaviors import (
|
|
FakeRectangularElevationBehavior,
|
|
RectangularRippleBehavior,
|
|
TouchBehavior,
|
|
)
|
|
from kivymd.uix.boxlayout import MDBoxLayout
|
|
from kivymd.uix.label import MDIcon
|
|
from kivymd.uix.stacklayout import MDStackLayout
|
|
from kivymd.uix.templates import ScaleWidget
|
|
|
|
with open(
|
|
os.path.join(uix_path, "chip", "chip.kv"), encoding="utf-8"
|
|
) as kv_file:
|
|
Builder.load_string(kv_file.read())
|
|
|
|
|
|
class MDChip(
|
|
ThemableBehavior,
|
|
RectangularRippleBehavior,
|
|
FakeRectangularElevationBehavior,
|
|
TouchBehavior,
|
|
ButtonBehavior,
|
|
MDBoxLayout,
|
|
):
|
|
text = StringProperty()
|
|
"""
|
|
Chip text.
|
|
|
|
:attr:`text` is an :class:`~kivy.properties.StringProperty`
|
|
and defaults to `''`.
|
|
"""
|
|
|
|
icon_left = StringProperty()
|
|
"""
|
|
Chip left icon.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`icon_left` is an :class:`~kivy.properties.StringProperty`
|
|
and defaults to `''`.
|
|
"""
|
|
|
|
icon_right = StringProperty()
|
|
"""
|
|
Chip right icon.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`icon_right` is an :class:`~kivy.properties.StringProperty`
|
|
and defaults to `''`.
|
|
"""
|
|
|
|
text_color = ColorProperty(None)
|
|
"""
|
|
Chip's text color in ``rgba`` format.
|
|
|
|
:attr:`text_color` is an :class:`~kivy.properties.ColorProperty`
|
|
and defaults to `None`.
|
|
"""
|
|
|
|
icon_right_color = ColorProperty(None)
|
|
"""
|
|
Chip's right icon color in ``rgba`` format.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`icon_right_color` is an :class:`~kivy.properties.ColorProperty`
|
|
and defaults to `None`.
|
|
"""
|
|
|
|
icon_left_color = ColorProperty(None)
|
|
"""
|
|
Chip's left icon color in ``rgba`` format.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`icon_left_color` is an :class:`~kivy.properties.ColorProperty`
|
|
and defaults to `None`.
|
|
"""
|
|
|
|
icon_check_color = ColorProperty(None)
|
|
"""
|
|
Chip's check icon color in ``rgba`` format.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`icon_check_color` is an :class:`~kivy.properties.ColorProperty`
|
|
and defaults to `None`.
|
|
"""
|
|
|
|
active = BooleanProperty(False)
|
|
"""
|
|
Whether the check is marked or not.
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
:attr:`active` is an :class:`~kivy.properties.BooleanProperty`
|
|
and defaults to `False`.
|
|
"""
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
|
|
def on_long_touch(self, *args) -> None:
|
|
if self.active:
|
|
return
|
|
self.active = True if not self.active else False
|
|
|
|
def on_active(self, instance_check, active_value: bool) -> None:
|
|
if active_value:
|
|
self.do_animation_check((0, 0, 0, 0.4), 1)
|
|
else:
|
|
self.do_animation_check((0, 0, 0, 0), 0)
|
|
|
|
def do_animation_check(self, md_bg_color: list, scale_value: int) -> None:
|
|
Animation(md_bg_color=md_bg_color, t="out_sine", d=0.1).start(
|
|
self.ids.icon_left_box
|
|
)
|
|
Animation(
|
|
scale_value_x=scale_value,
|
|
scale_value_y=scale_value,
|
|
scale_value_z=scale_value,
|
|
t="out_sine",
|
|
d=0.1,
|
|
).start(self.ids.check_icon)
|
|
|
|
if not self.icon_left:
|
|
if scale_value:
|
|
self.ids.check_icon.x = -dp(4)
|
|
Animation(size=(dp(24), dp(24)), t="out_sine", d=0.1).start(
|
|
self.ids.relative_box
|
|
)
|
|
else:
|
|
self.ids.check_icon.x = 0
|
|
Animation(size=(0, 0), t="out_sine", d=0.1).start(
|
|
self.ids.relative_box
|
|
)
|
|
|
|
def on_press(self, *args):
|
|
if self.active:
|
|
self.active = False
|
|
|
|
|
|
class MDScalableCheckIcon(MDIcon, ScaleWidget):
|
|
pos_hint = {"center_y": 0.5}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from kivymd.app import MDApp
|
|
from kivymd.uix.screen import MDScreen
|
|
|
|
KV = """
|
|
<MyScreen>
|
|
|
|
MDBoxLayout:
|
|
orientation: "vertical"
|
|
adaptive_size: True
|
|
spacing: "12dp"
|
|
padding: "56dp"
|
|
pos_hint: {"center_x": .5, "center_y": .5}
|
|
|
|
MDLabel:
|
|
text: "Multiple choose"
|
|
bold: True
|
|
font_style: "H5"
|
|
adaptive_size: True
|
|
|
|
MDBoxLayout:
|
|
id: chip_box
|
|
adaptive_size: True
|
|
spacing: "8dp"
|
|
|
|
MyChip:
|
|
text: "Elevator"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
MyChip:
|
|
text: "Washer / Dryer"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
MyChip:
|
|
text: "Fireplace"
|
|
on_press: if self.active: root.removes_marks_all_chips()
|
|
|
|
MDSeparator:
|
|
|
|
MDLabel:
|
|
text: "Only choose"
|
|
bold: True
|
|
font_style: "H5"
|
|
adaptive_size: True
|
|
|
|
MDBoxLayout:
|
|
id: chip_only_box
|
|
adaptive_size: True
|
|
spacing: "8dp"
|
|
|
|
MyChip:
|
|
text: "Elevator"
|
|
on_active: if self.active: root.removes_marks_all_chips(self, False)
|
|
|
|
MyChip:
|
|
text: "Washer / Dryer"
|
|
on_active: if self.active: root.removes_marks_all_chips(self, False)
|
|
|
|
MyChip:
|
|
text: "Fireplace"
|
|
on_active: if self.active: root.removes_marks_all_chips(self, False)
|
|
|
|
|
|
ScreenManager:
|
|
|
|
MyScreen:
|
|
"""
|
|
|
|
class MyChip(MDChip):
|
|
icon_check_color = (0, 0, 0, 1)
|
|
text_color = (0, 0, 0, 0.5)
|
|
_no_ripple_effect = True
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
self.bind(active=self.set_chip_bg_color)
|
|
self.bind(active=self.set_chip_text_color)
|
|
|
|
def set_chip_bg_color(self, instance_chip, active_value: int):
|
|
"""
|
|
Will be called every time the chip is activated/deactivated.
|
|
Sets the background color of the chip.
|
|
"""
|
|
|
|
self.md_bg_color = (
|
|
(0, 0, 0, 0.4)
|
|
if active_value
|
|
else (
|
|
self.theme_cls.bg_darkest
|
|
if self.theme_cls.theme_style == "Light"
|
|
else (
|
|
self.theme_cls.bg_light
|
|
if not self.disabled
|
|
else self.theme_cls.disabled_hint_text_color
|
|
)
|
|
)
|
|
)
|
|
|
|
def set_chip_text_color(self, instance_chip, active_value: int):
|
|
Animation(
|
|
color=(0, 0, 0, 1) if active_value else (0, 0, 0, 0.5), d=0.2
|
|
).start(self.ids.label)
|
|
|
|
class MyScreen(MDScreen):
|
|
def removes_marks_all_chips(
|
|
self, selected_instance_chip=None, multiple=True
|
|
):
|
|
if multiple:
|
|
for instance_chip in self.ids.chip_box.children:
|
|
if instance_chip.active:
|
|
instance_chip.active = False
|
|
else:
|
|
for instance_chip in self.ids.chip_only_box.children:
|
|
if instance_chip != selected_instance_chip:
|
|
instance_chip.active = False
|
|
|
|
class Test(MDApp):
|
|
def build(self):
|
|
return Builder.load_string(KV)
|
|
|
|
Test().run()
|