test-kivy-app/kivy_venv/lib/python3.11/site-packages/kivymd/uix/button/button.py
2024-09-15 20:57:02 +03:00

1290 lines
32 KiB
Python

"""
Components/Button
=================
.. seealso::
`Material Design spec, Buttons <https://m3.material.io/components/all-buttons>`_
.. rubric:: Buttons allow users to take actions, and make choices,
with a single tap. When choosing the right button for an action, consider
the level of emphasis each button type provides.
KivyMD provides the following button classes for use:
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/buttons.png
:align: center
1. Elevated button
2. Filled button
3. Filled tonal button
4. Outlined button
5. Text button
6. Icon button
7. Segmented button
8. Floating action button (FAB)
9. Extended FAB
Common buttons
==============
.. rubric:: Buttons help people take action, such as sending an email, sharing
a document, or liking a comment.
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/common-buttons.png
:align: center
1. Elevated button
2. Filled button
3. Filled tonal button
4. Outlined button
5. Text button
Elevated_
Filled_
Tonal_
Outlined_
Text_
.. Elevated:
Elevated
--------
.. tabs::
.. tab:: Declarative KV style
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
md_bg_color: app.theme_cls.surfaceColor
MDButton:
style: "elevated"
pos_hint: {"center_x": .5, "center_y": .5}
MDButtonIcon:
icon: "plus"
MDButtonText:
text: "Elevated"
'''
class Example(MDApp):
def build(self):
self.theme_cls.primary_palette = "Green"
return Builder.load_string(KV)
Example().run()
.. tab:: Declarative python style
.. code-block:: python
from kivymd.app import MDApp
from kivymd.uix.button import MDButton, MDButtonIcon, MDButtonText
from kivymd.uix.screen import MDScreen
class Example(MDApp):
def build(self):
self.theme_cls.primary_palette = "Green"
return (
MDScreen(
MDButton(
MDButtonIcon(
icon="plus",
),
MDButtonText(
text="Elevated",
),
style="elevated",
pos_hint={"center_x": 0.5, "center_y": 0.5},
),
md_bg_color=self.theme_cls.surfaceColor,
)
)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/elevated-button.gif
:align: center
Common buttons can contain an icon or be without an icon:
.. code-block:: kv
MDButton:
style: "elevated"
text: "Elevated"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/elevated-without-icon-button.png
:align: center
.. Filled:
Filled
------
.. code-block:: kv
MDButton:
style: "filled"
MDButtonText:
text: "Filled"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/filled-button.gif
:align: center
.. Tonal:
Tonal
-----
.. code-block:: kv
MDButton:
style: "tonal"
MDButtonText:
text: "Tonal"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/tonal-button.gif
:align: center
.. Outlined:
Outlined
--------
.. code-block:: kv
MDButton:
style: "outlined"
MDButtonText:
text: "Outlined"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/outlined-button.gif
:align: center
.. Text:
Text
----
.. code-block:: kv
MDButton:
style: "text"
MDButtonText:
text: "Text"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-button.gif
:align: center
Customization of buttons
========================
Text positioning and button size
--------------------------------
.. code-block:: kv
MDButton:
style: "tonal"
theme_width: "Custom"
height: "56dp"
size_hint_x: .5
MDButtonIcon:
x: text.x - (self.width + dp(10))
icon: "plus"
MDButtonText:
id: text
text: "Tonal"
pos_hint: {"center_x": .5, "center_y": .5}
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/positioning-size-button.png
:align: center
Font of the button text
-----------------------
.. code-block:: kv
MDButton:
style: "filled"
MDButtonIcon:
icon: "plus"
MDButtonText:
text: "Filled"
font_style: "Title"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-style-button-text.png
:align: center
.. code-block:: kv
MDButton:
style: "elevated"
MDButtonText:
text: "Elevated"
theme_font_name: "Custom"
font_name: "path/to/font.ttf"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-name-button-text.png
:align: center
Custom button color
-------------------
.. code-block:: kv
MDButton:
style: "elevated"
theme_shadow_color: "Custom"
shadow_color: "red"
MDButtonIcon:
icon: "plus"
theme_icon_color: "Custom"
icon_color: "green"
MDButtonText:
text: "Elevated"
theme_text_color: "Custom"
text_color: "red"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/custom-color-button.png
:align: center
Icon buttons
============
.. rubric:: Use icon buttons when a compact button is required, such as in a
toolbar or image list. There are two types of icon buttons: standard and
contained.
.. seealso::
`Material Design spec, Icon buttons <https://m3.material.io/components/icon-buttons/overview>`_
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-buttons.png
:align: center
1. Standard icon button
2. Contained icon button (including filled, filled tonal, and outlined styles)
StandardIcon_
FilledIcon_
TonalIcon_
OutlinedIcon_
.. StandardIcon:
StandardIcon
------------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "standard"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-standard.gif
:align: center
.. FilledIcon:
FilledIcon
----------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "filled"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-filled.gif
:align: center
.. TonalIcon:
TonalIcon
---------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "tonal"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-tonal.gif
:align: center
.. OutlinedIcon:
OutlinedIcon
------------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "outlined"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-outlined.gif
:align: center
Custom icon size
----------------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "tonal"
theme_font_size: "Custom"
font_size: "48sp"
radius: [self.height / 2, ]
size_hint: None, None
size: "84dp", "84dp"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-size.png
:align: center
Custom button color
-------------------
.. code-block:: kv
MDIconButton:
icon: "heart-outline"
style: "tonal"
theme_bg_color: "Custom"
md_bg_color: "brown"
theme_icon_color: "Custom"
icon_color: "white"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/icon-button-color.png
:align: center
FAB buttons
===========
.. rubric:: The FAB represents the most important action on a screen.
It puts key actions within reach.
.. seealso::
`Material Design spec, FAB buttons <https://m3.material.io/components/floating-action-button/overview>`_
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-buttons.png
:align: center
1. Standard FAB
2. Small FAB
3. Large FAB
There are three sizes of floating action buttons: FAB, small FAB, and large FAB:
Standard_
Small_
Large_
.. Standard:
Standard
--------
.. code-block:: kv
MDFabButton:
icon: "pencil-outline"
style: "standard"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-button-standard.gif
:align: center
.. Small:
Small
-----
.. code-block:: kv
MDFabButton:
icon: "pencil-outline"
style: "small"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-button-small.png
:align: center
.. Large:
Large
-----
.. code-block:: kv
MDFabButton:
icon: "pencil-outline"
style: "large"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-button-large.gif
:align: center
Additional color mappings
-------------------------
FABs can use other combinations of container and icon colors. The color
mappings below provide the same legibility and functionality as the default,
so the color mapping you use depends on style alone.
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-color-mapping.png
:align: center
1. Surface
2. Secondary
3. Tertiary
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.button import MDFabButton
KV = '''
MDScreen:
md_bg_color: app.theme_cls.surfaceColor
MDBoxLayout:
id: box
adaptive_size: True
spacing: "32dp"
pos_hint: {"center_x": .5, "center_y": .5}
'''
class Example(MDApp):
def build(self):
self.theme_cls.primary_palette = "Green"
return Builder.load_string(KV)
def on_start(self):
styles = {
"standard": "surface",
"small": "secondary",
"large": "tertiary",
}
for style in styles.keys():
self.root.ids.box.add_widget(
MDFabButton(
style=style, icon="pencil-outline", color_map=styles[style]
)
)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fab-button-color-mapping.png
:align: center
Extended FAB
============
.. rubric:: Extended floating action buttons (extended FABs) help people take
primary actions. They're wider than FABs to accommodate a text label and
larger target area.
.. seealso::
`Material Design spec, FAB extended buttons <https://m3.material.io/components/extended-fab/overview>`_
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/extended-fab-button.png
:align: center
1. Extended FAB with both icon and label text
2. Extended FAB without icon
With icon
---------
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
md_bg_color: app.theme_cls.surfaceColor
on_touch_down:
if not btn.collide_point(*args[1].pos): \\
btn.fab_state = "expand" \\
if btn.fab_state == "collapse" else "collapse"
MDExtendedFabButton:
id: btn
pos_hint: {"center_x": .5, "center_y": .5}
MDExtendedFabButtonIcon:
icon: "pencil-outline"
MDExtendedFabButtonText:
text: "Compose"
'''
class Example(MDApp):
def build(self):
self.theme_cls.primary_palette = "Green"
return Builder.load_string(KV)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/extended-fab-button-icon.gif
:align: center
Without icon
------------
.. code-block:: kv
MDExtendedFabButton:
fab_state: "expand"
MDExtendedFabButtonText:
text: "Compose"
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/extended-fab-button-without-icon.png
:align: center
API break
=========
1.2.0 version
-------------
.. code-block:: kv
MDFloatingActionButton:
icon: "plus"
.. code-block:: kv
MDRoundFlatButton:
text: "Outlined"
.. code-block:: kv
MDRoundFlatIconButton:
text: "Outlined with icon"
icon: "plus"
.. code-block:: kv
MDFillRoundFlatButton
text: "Filled"
.. code-block:: kv
MDFillRoundFlatIconButton
text: "Filled with icon"
icon: "plus"
2.0.0 version
-------------
.. note:: `MDFloatingActionButtonSpeedDial` type buttons were removed
in version `2.0.0`.
.. code-block:: kv
MDFabButton:
icon: "plus"
.. code-block:: kv
MDButton:
style: "outlined"
MDButtonText:
text: "Outlined"
.. code-block:: kv
MDButton:
style: "outlined"
MDButtonIcon:
icon: "plus"
MDButtonText:
text: "Outlined with icon"
.. code-block:: kv
MDButton:
style: "filled"
MDButtonText:
text: "Filled"
.. code-block:: kv
MDButton:
style: "filled"
MDButtonIcon:
icon: "plus"
MDButtonText:
text: "Filled"
"""
from __future__ import annotations
__all__ = (
"MDIconButton",
"MDButtonText",
"MDButtonIcon",
"MDFabButton",
"MDExtendedFabButton",
"MDExtendedFabButtonIcon",
"MDExtendedFabButtonText",
"MDButton",
"BaseButton",
"BaseFabButton",
)
import os
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import (
ColorProperty,
NumericProperty,
OptionProperty,
VariableListProperty,
ObjectProperty, DictProperty,
)
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.relativelayout import RelativeLayout
from kivymd.uix.label import MDIcon, MDLabel
from kivymd import uix_path
from kivymd.theming import ThemableBehavior
from kivymd.uix.behaviors import (
CommonElevationBehavior,
DeclarativeBehavior,
RectangularRippleBehavior,
BackgroundColorBehavior,
)
from kivymd.uix.behaviors.motion_behavior import MotionExtendedFabButtonBehavior
from kivymd.uix.behaviors.state_layer_behavior import StateLayerBehavior
with open(
os.path.join(uix_path, "button", "button.kv"), encoding="utf-8"
) as kv_file:
Builder.load_string(kv_file.read())
class BaseFabButton:
"""
Implements the basic properties for the
:class:`~MDExtendedFabButton` and :class:`~MDFabButton` classes.
.. versionadded:: 2.0.0
"""
elevation_levels = DictProperty(
{
0: 0,
1: dp(4),
2: dp(8),
3: dp(12),
4: dp(16),
5: dp(18),
}
)
"""
Elevation is measured as the distance between components along the z-axis
in density-independent pixels (dps).
.. versionadded:: 1.2.0
:attr:`elevation_levels` is an :class:`~kivy.properties.DictProperty`
and defaults to `{0: dp(0), 1: dp(4), 2: dp(8), 3: dp(12), 4: dp(16), 5: dp(18)}`.
"""
color_map = OptionProperty(
"surface", options=("surface", "secondary", "tertiary")
)
"""
Additional color mappings.
Available options are: 'surface', 'secondary', 'tertiary'.
:attr:`color_map` is an :class:`~kivy.properties.OptionProperty`
and defaults to `'secondary'`.
"""
icon_color_disabled = ColorProperty(None)
"""
The icon color in (r, g, b, a) or string format of the list item when
the widget item is disabled.
:attr:`icon_color_disabled` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
style = OptionProperty("standard", options=("standard", "small", "large"))
"""
Button type.
Available options are: 'standard', 'small', 'large'.
:attr:`style` is an :class:`~kivy.properties.OptionProperty`
and defaults to `'standard'`.
"""
fab_state = OptionProperty("collapse", options=("collapse", "expand"))
"""
The state of the button.
Available options are: 'collapse' or 'expand'.
:attr:`fab_state` is an :class:`~kivy.properties.OptionProperty`
and defaults to "collapse".
"""
md_bg_color_disabled = ColorProperty(None)
"""
The background color in (r, g, b, a) or string format of the list item when
the list button is disabled.
:attr:`md_bg_color_disabled` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
radius = VariableListProperty(
[
dp(16),
],
length=4,
)
"""
Canvas radius.
:attr:`radius` is an :class:`~kivy.properties.VariableListProperty`
and defaults to `[dp(16), dp(16), dp(16), dp(16)]`.
"""
class BaseButton(
DeclarativeBehavior,
BackgroundColorBehavior,
RectangularRippleBehavior,
ButtonBehavior,
ThemableBehavior,
StateLayerBehavior,
):
"""
Base button class.
For more information, see in the
:class:`~kivymd.uix.behaviors.declarative_behavior.DeclarativeBehavior` and
:class:`~kivymd.uix.behaviors.backgroundcolor_behavior.BackgroundColorBehavior` and
:class:`~kivymd.uix.behaviors.ripple_behavior.RectangularRippleBehavior` and
:class:`~kivy.uix.behaviors.ButtonBehavior` and
:class:`~kivymd.theming.ThemableBehavior` and
:class:`~kivymd.uix.behaviors.state_layer_behavior.StateLayerBehavior`
classes documentation.
"""
elevation_levels = DictProperty(
{
0: 0,
1: dp(4),
2: dp(8),
3: dp(12),
4: dp(16),
5: dp(18),
}
)
"""
Elevation is measured as the distance between components along the z-axis
in density-independent pixels (dps).
.. versionadded:: 1.2.0
:attr:`elevation_levels` is an :class:`~kivy.properties.DictProperty`
and defaults to `{0: dp(0), 1: dp(4), 2: dp(8), 3: dp(12), 4: dp(16), 5: dp(18)}`.
"""
md_bg_color_disabled = ColorProperty(None)
"""
The background color in (r, g, b, a) or string format of the button when
the button is disabled.
:attr:`md_bg_color_disabled` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
shadow_radius = VariableListProperty([0, 0, 0, 0])
"""
Button shadow radius.
:attr:`shadow_radius` is an :class:`~kivy.properties.VariableListProperty`
and defaults to `[0, 0, 0, 0]`.
"""
md_bg_color = ColorProperty(None)
"""
Button background color in (r, g, b, a) or string format.
:attr:`md_bg_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
line_color = ColorProperty(None)
"""
Outlined color.
:attr:`line_color` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
line_width = NumericProperty(1)
"""
Line width for button border.
:attr:`line_width` is a :class:`~kivy.properties.NumericProperty`
and defaults to `1`.
"""
def on_press(self, *args) -> None:
"""Fired when the button is pressed."""
self._on_press(args)
def on_release(self, *args) -> None:
"""
Fired when the button is released
(i.e. the touch/click that pressed the button goes away).
"""
self._on_release(args)
class MDButton(BaseButton, CommonElevationBehavior, RelativeLayout):
"""
Base class for all buttons.
.. versionadded:: 2.2.0
For more information, see in the
:class:`~kivymd.uix.behaviors.elevation.CommonElevationBehavior` and
:class:`~BaseButton` and
:class:`~kivy.uix.relativelayout.RelativeLayout`
classes documentation.
"""
style = OptionProperty(
"elevated", options=("elevated", "filled", "tonal", "outlined", "text")
)
"""
Button type.
Available options are: 'filled', 'elevated', 'outlined', 'tonal', 'text'.
:attr:`style` is an :class:`~kivy.properties.OptionProperty`
and defaults to `'elevated'`.
"""
radius = VariableListProperty(
[
dp(20),
]
)
"""
Button radius.
:attr:`radius` is an :class:`~kivy.properties.VariableListProperty`
and defaults to `[dp(20), dp(20), dp(20), dp(20)]`.
"""
# kivymd.uix.button.button.MDButtonIcon object.
_button_icon = ObjectProperty()
# kivymd.uix.button.button.MDButtonText object.
_button_text = ObjectProperty()
_icon_left_pad = dp(16)
_spacing_between_icon_text = dp(10)
_text_right_pad = dp(24)
_text_left_pad = dp(24)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Clock.schedule_once(self.adjust_width, 0.2)
Clock.schedule_once(self.adjust_pos, 0.2)
def adjust_pos(self, *args) -> None:
"""Adjusts the pos of the button according to the content."""
if self._button_icon and self._button_text:
self._button_text.x = (
self._button_icon.x
+ self._spacing_between_icon_text
+ self._icon_left_pad
+ dp(2)
)
elif not self._button_icon and self._button_text:
self._button_text.x = self._text_left_pad
def adjust_width(self, *args) -> None:
"""Adjusts the width of the button according to the content."""
if self._button_icon and self._button_text:
if self.theme_width == "Primary":
self.width = (
self._button_icon.texture_size[0]
+ self._button_text.texture_size[0]
+ self._icon_left_pad
+ self._spacing_between_icon_text
+ self._text_right_pad
)
elif not self._button_icon and self._button_text:
if self.theme_width == "Primary":
self.width = (
self._button_text.texture_size[0]
+ self._text_left_pad
+ self._text_right_pad
)
elif self._button_icon and not self._button_text:
if self.theme_width == "Primary":
self.width = (
dp(48)
+ self._button_icon.texture_size[0]
- self._spacing_between_icon_text
)
def add_widget(self, widget, *args, **kwargs):
if isinstance(widget, MDButtonText):
self._button_text = widget
widget.bind(
text=lambda x, y: Clock.schedule_once(self.adjust_width, 0.2)
)
widget._button = self
elif isinstance(widget, MDButtonIcon):
self._button_icon = widget
widget._button = self
if isinstance(widget, (MDButtonIcon, MDButtonText)):
return super().add_widget(widget)
def set_properties_widget(self) -> None:
"""Fired `on_release/on_press/on_enter/on_leave` events."""
super().set_properties_widget()
if (
self._state == self.state_hover
and self.focus_behavior
or self._state == self.state_press
):
self._elevation_level = (
1
if self.theme_elevation_level == "Primary"
else self.elevation_level
)
self._shadow_softness = (
0
if self.theme_shadow_softness == "Primary"
else self.shadow_softness
)
if not self.disabled:
if self._state == self.state_hover and self.focus_behavior:
if self.style == "elevated":
self.elevation_level = 2
self.shadow_softness = 2
elif self._state == self.state_press:
if self.style == "elevated":
self.elevation_level = 2
self.shadow_softness = 2
elif not self._state:
if self.style == "elevated":
self.elevation_level = 1
self.shadow_softness = 0
class MDButtonText(MDLabel):
"""
The class implements the text for the :class:`~MDButton` class.
For more information, see in the
:class:`~kivymd.uix.label.label.MDLabel` class documentation.
"""
# kivymd.uix.button.button.MDButton object.
_button = ObjectProperty()
class MDButtonIcon(MDIcon):
"""
The class implements an icon for the :class:`~MDButton` class.
For more information, see in the
:class:`~kivymd.uix.label.label.MDIcon` class documentation.
"""
# kivymd.uix.button.button.MDButton object.
_button = ObjectProperty()
class MDIconButton(RectangularRippleBehavior, ButtonBehavior, MDIcon):
"""
Base class for icon buttons.
For more information, see in the
:class:`~kivymd.uix.behaviors.ripple_behavior.RectangularRippleBehavior` and
:class:`~kivy.uix.behaviors.ButtonBehavior` and
:class:`~kivy.uix.label.label.MDIcon`
classes documentation.
"""
style = OptionProperty(
"standard", options=("standard", "filled", "tonal", "outlined")
)
"""
Button type.
.. versionadded:: 2.0.0
Available options are: 'standard', 'filled', 'tonal', 'outlined'.
:attr:`style` is an :class:`~kivy.properties.OptionProperty`
and defaults to `'standard'`.
"""
md_bg_color_disabled = ColorProperty(None)
"""
The background color in (r, g, b, a) or string format of the list item when
the list button is disabled.
:attr:`md_bg_color_disabled` is a :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
_line_color = ColorProperty(None)
def on_line_color(self, instance, value) -> None:
"""Fired when the values of :attr:`line_color` change."""
if not self.disabled and self.theme_line_color == "Custom":
self._line_color = value
class MDFabButton(
BaseFabButton,
CommonElevationBehavior,
RectangularRippleBehavior,
ButtonBehavior,
MDIcon,
):
"""
Base class for FAB buttons.
For more information, see in the
:class:`~BaseFabButton` and
:class:`~kivymd.uix.behaviors.elevation.CommonElevationBehavior` and
:class:`~kivymd.uix.behaviors.ripple_behavior.RectangularRippleBehavior` and
:class:`~kivy.uix.behaviors.ButtonBehavior` and
:class:`~kivymd.uix.label.label.MDIcon`
classes documentation.
"""
def on_press(self, *args) -> None:
"""Fired when the button is pressed."""
self._on_press(args)
def on_release(self, *args) -> None:
"""
Fired when the button is released
(i.e. the touch/click that pressed the button goes away).
"""
self._on_release(args)
def set_properties_widget(self) -> None:
"""Fired `on_release/on_press/on_enter/on_leave` events."""
super().set_properties_widget()
if (
self._state == self.state_hover
and self.focus_behavior
or self._state == self.state_press
):
self._elevation_level = (
1
if self.theme_elevation_level == "Primary"
else self.elevation_level
)
self._shadow_softness = (
0
if self.theme_shadow_softness == "Primary"
else self.shadow_softness
)
if not self.disabled:
if (
self._state == self.state_hover and self.focus_behavior
):
self.elevation_level = 1
self.shadow_softness = 0
elif self._state == self.state_press:
self.elevation_level = 2
self.shadow_softness = 2
elif not self._state:
self.elevation_level = 1
self.shadow_softness = 0
class MDExtendedFabButtonIcon(MDIcon):
"""
Implements an icon for the :class:`~MDExtendedFabButton` class.
.. versionadded:: 2.0.0
"""
class MDExtendedFabButtonText(MDLabel):
"""
Implements the text for the class :class:`~MDExtendedFabButton` class.
.. versionadded:: 2.0.0
"""
class MDExtendedFabButton(
DeclarativeBehavior,
ThemableBehavior,
MotionExtendedFabButtonBehavior,
CommonElevationBehavior,
StateLayerBehavior,
BaseFabButton,
ButtonBehavior,
RelativeLayout,
):
"""
Base class for Extended FAB buttons.
.. versionadded:: 2.0.0
For more information, see in the
:class:`~kivymd.uix.behaviors.declarative_behavior.DeclarativeBehavior` and
:class:`~kivymd.theming.ThemableBehavior` and
:class:`~kivymd.uix.behaviors.motion_behavior.MotionExtendedFabButtonBehavior` and
:class:`~kivymd.uix.behaviors.elevation.CommonElevationBehavior` and
:class:`~kivymd.uix.behaviors.state_layer_behavior.StateLayerBehavior` and
:class:`~BaseFabButton` and
:class:`~kivy.uix.behaviors.ButtonBehavior` and
:class:`~kivy.uix.relativelayout.RelativeLayout`
classes documentation.
:Events:
`on_collapse`
Fired when the button is collapsed.
`on_expand`
Fired when the button is expanded.
"""
elevation_levels = DictProperty(
{
0: 0,
1: dp(4),
2: dp(8),
3: dp(12),
4: dp(16),
5: dp(18),
}
)
"""
Elevation is measured as the distance between components along the z-axis
in density-independent pixels (dps).
.. versionadded:: 1.2.0
:attr:`elevation_levels` is an :class:`~kivy.properties.DictProperty`
and defaults to `{0: dp(0), 1: dp(4), 2: dp(8), 3: dp(12), 4: dp(16), 5: dp(18)}`.
"""
_icon = ObjectProperty()
_label = ObjectProperty()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.register_event_type("on_collapse")
self.register_event_type("on_expand")
Clock.schedule_once(self._set_text_pos, 0.5)
def add_widget(self, widget, *args, **kwargs):
if isinstance(widget, MDExtendedFabButtonIcon):
self._icon = widget
elif isinstance(widget, MDExtendedFabButtonText):
self._label = widget
widget.opacity = 0
return super().add_widget(widget)
def on_collapse(self, *args):
"""Fired when the button is collapsed."""
def on_expand(self, *args):
"""Fired when the button is expanded."""
def on_fab_state(self, instance, state: str) -> None:
"""Fired when the :attr:`fab_state` value changes."""
if state == "expand":
Clock.schedule_once(self.expand)
Clock.schedule_once(lambda x: self.dispatch("on_expand"))
elif state == "collapse":
Clock.schedule_once(self.collapse)
Clock.schedule_once(lambda x: self.dispatch("on_collapse"))
def on__x(self, instance, value) -> None:
self._label.x = (
self._icon.x + self._icon.texture_size[0] + dp(24) - value
)
def _set_text_pos(self, *args):
if self._icon and self._label:
self._label.x = self._icon.x + self._icon.texture_size[0] + dp(24)
elif not self._icon and self._label:
self._label.opacity = 1
self.width = self._label.texture_size[0] + dp(32)
self._label.pos_hint = {"center_x": 0.5}