Updated kivymd
@ -9,23 +9,16 @@ Is a collection of Material Design compliant widgets for use with,
 | 
			
		||||
a framework for cross-platform, touch-enabled graphical applications.
 | 
			
		||||
The project's goal is to approximate Google's `Material Design spec
 | 
			
		||||
<https://material.io/design/introduction>`_ as close as possible without
 | 
			
		||||
sacrificing ease of use or application performance.
 | 
			
		||||
sacrificing ease of use.
 | 
			
		||||
 | 
			
		||||
This library is a fork of the `KivyMD project
 | 
			
		||||
<https://gitlab.com/kivymd/KivyMD>`_ the author of which stopped supporting
 | 
			
		||||
this project three years ago. We found the strength and brought this project
 | 
			
		||||
to a new level. Currently we're in **beta** status, so things are changing
 | 
			
		||||
all the time and we cannot promise any kind of API stability.
 | 
			
		||||
However it is safe to vendor now and make use of what's currently available.
 | 
			
		||||
<https://gitlab.com/kivymd/KivyMD>`_. We found the strength and brought this
 | 
			
		||||
project to a new level.
 | 
			
		||||
 | 
			
		||||
Join the project! Just fork the project, branch out and submit a pull request
 | 
			
		||||
when your patch is ready. If any changes are necessary, we'll guide you
 | 
			
		||||
through the steps that need to be done via PR comments or access to your for
 | 
			
		||||
may be requested to outright submit them. If you wish to become a project
 | 
			
		||||
developer (permission to create branches on the project without forking for
 | 
			
		||||
easier collaboration), have at least one PR approved and ask for it.
 | 
			
		||||
If you contribute regularly to the project the role may be offered to you
 | 
			
		||||
without asking too.
 | 
			
		||||
If you wish to become a project developer (permission to create branches on the
 | 
			
		||||
project without forking for easier collaboration), have at least one PR
 | 
			
		||||
approved and ask for it. If you contribute regularly to the project the role
 | 
			
		||||
may be offered to you without asking too.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
@ -33,7 +26,7 @@ import os
 | 
			
		||||
import kivy
 | 
			
		||||
from kivy.logger import Logger
 | 
			
		||||
 | 
			
		||||
__version__ = "1.0.0.dev0"
 | 
			
		||||
__version__ = "1.1.0.dev0"
 | 
			
		||||
"""KivyMD version."""
 | 
			
		||||
 | 
			
		||||
release = False
 | 
			
		||||
@ -56,6 +49,9 @@ images_path = os.path.join(path, f"images{os.sep}")
 | 
			
		||||
uix_path = os.path.join(path, "uix")
 | 
			
		||||
"""Path to uix directory."""
 | 
			
		||||
 | 
			
		||||
glsl_path = os.path.join(path, "data", "glsl")
 | 
			
		||||
"""Path to glsl directory."""
 | 
			
		||||
 | 
			
		||||
_log_message = (
 | 
			
		||||
    "KivyMD:"
 | 
			
		||||
    + (" Release" if release else "")
 | 
			
		||||
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
# THIS FILE IS GENERATED FROM KIVYMD SETUP.PY
 | 
			
		||||
__version__ = '1.0.0.dev0'
 | 
			
		||||
__hash__ = '68ec8626a93b0e7f69e48d9755c4af70028f66a2'
 | 
			
		||||
__short_hash__ = '68ec862'
 | 
			
		||||
__date__ = '2022-07-07'
 | 
			
		||||
@ -45,7 +45,7 @@ import os
 | 
			
		||||
from kivy.app import App
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.logger import Logger
 | 
			
		||||
from kivy.properties import ObjectProperty
 | 
			
		||||
from kivy.properties import ObjectProperty, StringProperty
 | 
			
		||||
 | 
			
		||||
from kivymd.theming import ThemeManager
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,16 @@ class MDApp(App, FpsMonitoring):
 | 
			
		||||
    information.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    icon = StringProperty("kivymd/images/logo/kivymd-icon-512.png")
 | 
			
		||||
    """
 | 
			
		||||
    See :attr:`~kivy.app.App.icon` attribute for more information.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`icon` is an :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    adn default to `kivymd/images/logo/kivymd-icon-512.png`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    theme_cls = ObjectProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Instance of :class:`~ThemeManager` class.
 | 
			
		||||
 | 
			
		||||
@ -412,7 +412,7 @@ To demonstrate the shades of the palette, you can run the following code:
 | 
			
		||||
            self.screen = Factory.Root()
 | 
			
		||||
 | 
			
		||||
            for name_tab in colors.keys():
 | 
			
		||||
                tab = Tab(text=name_tab)
 | 
			
		||||
                tab = Tab(title=name_tab)
 | 
			
		||||
                self.screen.ids.android_tabs.add_widget(tab)
 | 
			
		||||
            return self.screen
 | 
			
		||||
 | 
			
		||||
@ -427,7 +427,7 @@ To demonstrate the shades of the palette, you can run the following code:
 | 
			
		||||
                    {
 | 
			
		||||
                        "viewclass": "ItemColor",
 | 
			
		||||
                        "md_bg_color": colors[tab_text][value_color],
 | 
			
		||||
                        "text": value_color,
 | 
			
		||||
                        "title": value_color,
 | 
			
		||||
                    }
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										44
									
								
								sbapp/kivymd/data/glsl/elevation/elevation.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
The shader code has been refactored for the KivyMD library.
 | 
			
		||||
You can find the original code of this shaders at the links:
 | 
			
		||||
 | 
			
		||||
https://www.shadertoy.com/view/WtdSDs
 | 
			
		||||
https://www.shadertoy.com/view/fsdyzB
 | 
			
		||||
 | 
			
		||||
Additional thanks to iq for optimizing conditional block for individual
 | 
			
		||||
corner radius:
 | 
			
		||||
https://iquilezles.org/articles/distfunctions
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
float roundedBoxSDF(vec2 centerPosition, vec2 size, vec4 radius) {
 | 
			
		||||
    radius.xy = (centerPosition.x > 0.0) ? radius.xy : radius.zw;
 | 
			
		||||
    radius.x = (centerPosition.y > 0.0) ? radius.x : radius.y;
 | 
			
		||||
 | 
			
		||||
    vec2 q = abs(centerPosition) - (size - shadow_softness) + radius.x;
 | 
			
		||||
    return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius.x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
 | 
			
		||||
    // Smooth the result (free antialiasing).
 | 
			
		||||
    float edge0 = 0.0;
 | 
			
		||||
    float smoothedAlpha = 1.0 - smoothstep(0.0, edge0, 1.0);
 | 
			
		||||
    // Get the resultant shape.
 | 
			
		||||
    vec4 quadColor = mix(
 | 
			
		||||
        vec4(
 | 
			
		||||
            shadow_color[0],
 | 
			
		||||
            shadow_color[1],
 | 
			
		||||
            shadow_color[2],
 | 
			
		||||
            0.0
 | 
			
		||||
        ),
 | 
			
		||||
        shadow_color,
 | 
			
		||||
        smoothedAlpha
 | 
			
		||||
    );
 | 
			
		||||
    // Apply a drop shadow effect.
 | 
			
		||||
    float shadowDistance = roundedBoxSDF(
 | 
			
		||||
        fragCoord.xy - mouse.xy - (size / 2.0), size / 2.0, shadow_radius
 | 
			
		||||
    );
 | 
			
		||||
    float shadowAlpha = 1.0 - smoothstep(
 | 
			
		||||
        -shadow_softness, shadow_softness, shadowDistance
 | 
			
		||||
    );
 | 
			
		||||
    fragColor = mix(quadColor, shadow_color, shadowAlpha - smoothedAlpha);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								sbapp/kivymd/data/glsl/elevation/header.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
			
		||||
#ifdef GL_ES
 | 
			
		||||
    precision highp float;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uniform vec4 resolution;
 | 
			
		||||
uniform vec4 mouse;
 | 
			
		||||
uniform vec2 size;
 | 
			
		||||
uniform vec4 shadow_radius;
 | 
			
		||||
uniform float shadow_softness;
 | 
			
		||||
uniform vec4 shadow_color;
 | 
			
		||||
							
								
								
									
										10
									
								
								sbapp/kivymd/data/glsl/elevation/main.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
			
		||||
vec2 gfc(in vec4 fc) {
 | 
			
		||||
	vec2 canvas_pos = resolution.zw;
 | 
			
		||||
	vec2 uv = fc.xy;
 | 
			
		||||
    uv.y -= canvas_pos.y;
 | 
			
		||||
	return uv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main(void) {
 | 
			
		||||
    mainImage(gl_FragColor, gfc(gl_FragCoord));
 | 
			
		||||
}
 | 
			
		||||
@ -5,11 +5,15 @@ Register KivyMD widgets to use without import.
 | 
			
		||||
from kivy.factory import Factory
 | 
			
		||||
 | 
			
		||||
register = Factory.register
 | 
			
		||||
register("MDScrollView", module="kivymd.uix.scrollview")
 | 
			
		||||
register("MDRecycleView", module="kivymd.uix.recycleview")
 | 
			
		||||
register("MDResponsiveLayout", module="kivymd.uix.responsivelayout")
 | 
			
		||||
register("MDSegmentedControl", module="kivymd.uix.segmentedcontrol")
 | 
			
		||||
register("MDSegmentedControlItem", module="kivymd.uix.segmentedcontrol")
 | 
			
		||||
register("MDSliverAppbar", module="kivymd.uix.sliverappbar")
 | 
			
		||||
register("MDSliverAppbarContent", module="kivymd.uix.sliverappbar")
 | 
			
		||||
register("MDSliverAppbarHeader", module="kivymd.uix.sliverappbar")
 | 
			
		||||
register("MDNavigationRailItem", module="kivymd.uix.navigationrail")
 | 
			
		||||
register("MDNavigationRail", module="kivymd.uix.navigationrail")
 | 
			
		||||
register("MDNavigationRailFabButton", module="kivymd.uix.navigationrail")
 | 
			
		||||
register("MDNavigationRailMenuButton", module="kivymd.uix.navigationrail")
 | 
			
		||||
@ -29,7 +33,7 @@ register("MDExpansionPanel", module="kivymd.uix.expansionpanel")
 | 
			
		||||
register("MDExpansionPanelOneLine", module="kivymd.uix.expansionpanel")
 | 
			
		||||
register("MDExpansionPanelTwoLine", module="kivymd.uix.expansionpanel")
 | 
			
		||||
register("MDExpansionPanelThreeLine", module="kivymd.uix.expansionpanel")
 | 
			
		||||
register("FitImage", module="kivymd.utils.fitimage")
 | 
			
		||||
register("FitImage", module="kivymd.uix.fitimage")
 | 
			
		||||
register("MDBackdrop", module="kivymd.uix.backdrop")
 | 
			
		||||
register("MDBanner", module="kivymd.uix.banner")
 | 
			
		||||
register("MDTooltip", module="kivymd.uix.tooltip")
 | 
			
		||||
@ -54,10 +58,7 @@ register("MDCard", module="kivymd.uix.card")
 | 
			
		||||
register("MDSeparator", module="kivymd.uix.card")
 | 
			
		||||
register("MDSelectionList", module="kivymd.uix.selection")
 | 
			
		||||
register("MDChip", module="kivymd.uix.chip")
 | 
			
		||||
register("MDChooseChip", module="kivymd.uix.chip")
 | 
			
		||||
register("MDSmartTile", module="kivymd.uix.imagelist")
 | 
			
		||||
register("SmartTileWithLabel", module="kivymd.uix.imagelist")
 | 
			
		||||
register("SmartTileWithStar", module="kivymd.uix.imagelist")
 | 
			
		||||
register("MDLabel", module="kivymd.uix.label")
 | 
			
		||||
register("MDIcon", module="kivymd.uix.label")
 | 
			
		||||
register("MDList", module="kivymd.uix.list")
 | 
			
		||||
@ -65,7 +66,6 @@ register("ILeftBody", module="kivymd.uix.list")
 | 
			
		||||
register("ILeftBodyTouch", module="kivymd.uix.list")
 | 
			
		||||
register("IRightBody", module="kivymd.uix.list")
 | 
			
		||||
register("IRightBodyTouch", module="kivymd.uix.list")
 | 
			
		||||
register("ContainerSupport", module="kivymd.uix.list")
 | 
			
		||||
register("OneLineListItem", module="kivymd.uix.list")
 | 
			
		||||
register("TwoLineListItem", module="kivymd.uix.list")
 | 
			
		||||
register("ThreeLineListItem", module="kivymd.uix.list")
 | 
			
		||||
@ -99,9 +99,7 @@ register("MDSlider", module="kivymd.uix.slider")
 | 
			
		||||
register("MDSpinner", module="kivymd.uix.spinner")
 | 
			
		||||
register("MDTabs", module="kivymd.uix.tab")
 | 
			
		||||
register("MDTextField", module="kivymd.uix.textfield")
 | 
			
		||||
register("MDTextFieldRound", module="kivymd.uix.textfield")
 | 
			
		||||
register("MDTextFieldRect", module="kivymd.uix.textfield")
 | 
			
		||||
register("MDToolbar", module="kivymd.uix.toolbar")
 | 
			
		||||
register("MDTopAppBar", module="kivymd.uix.toolbar")
 | 
			
		||||
register("MDBottomAppBar", module="kivymd.uix.toolbar")
 | 
			
		||||
register("MDDropDownItem", module="kivymd.uix.dropdownitem")
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ Themes/Icon Definitions
 | 
			
		||||
List of icons from materialdesignicons.com. These expanded material design
 | 
			
		||||
icons are maintained by Austin Andrews (Templarian on Github).
 | 
			
		||||
 | 
			
		||||
LAST UPDATED: Version 6.9.96
 | 
			
		||||
LAST UPDATED: Version 7.0.96
 | 
			
		||||
 | 
			
		||||
To preview the icons and their names, you can use the following application:
 | 
			
		||||
----------------------------------------------------------------------------
 | 
			
		||||
@ -154,6 +154,8 @@ md_icons = {
 | 
			
		||||
    "account-box-outline": "\U000F0007",
 | 
			
		||||
    "account-cancel": "\U000F12DF",
 | 
			
		||||
    "account-cancel-outline": "\U000F12E0",
 | 
			
		||||
    "account-card": "\U000F1BA4",
 | 
			
		||||
    "account-card-outline": "\U000F1BA5",
 | 
			
		||||
    "account-cash": "\U000F1097",
 | 
			
		||||
    "account-cash-outline": "\U000F1098",
 | 
			
		||||
    "account-check": "\U000F0008",
 | 
			
		||||
@ -171,6 +173,8 @@ md_icons = {
 | 
			
		||||
    "account-convert-outline": "\U000F1301",
 | 
			
		||||
    "account-cowboy-hat": "\U000F0E9B",
 | 
			
		||||
    "account-cowboy-hat-outline": "\U000F17F3",
 | 
			
		||||
    "account-credit-card": "\U000F1BA6",
 | 
			
		||||
    "account-credit-card-outline": "\U000F1BA7",
 | 
			
		||||
    "account-details": "\U000F0631",
 | 
			
		||||
    "account-details-outline": "\U000F1372",
 | 
			
		||||
    "account-edit": "\U000F06BC",
 | 
			
		||||
@ -260,6 +264,7 @@ md_icons = {
 | 
			
		||||
    "air-humidifier": "\U000F1099",
 | 
			
		||||
    "air-humidifier-off": "\U000F1466",
 | 
			
		||||
    "air-purifier": "\U000F0D44",
 | 
			
		||||
    "air-purifier-off": "\U000F1B57",
 | 
			
		||||
    "airbag": "\U000F0BE9",
 | 
			
		||||
    "airballoon": "\U000F001C",
 | 
			
		||||
    "airballoon-outline": "\U000F100B",
 | 
			
		||||
@ -480,7 +485,6 @@ md_icons = {
 | 
			
		||||
    "amplifier-off": "\U000F11B5",
 | 
			
		||||
    "anchor": "\U000F0031",
 | 
			
		||||
    "android": "\U000F0032",
 | 
			
		||||
    "android-messages": "\U000F0D45",
 | 
			
		||||
    "android-studio": "\U000F0034",
 | 
			
		||||
    "angle-acute": "\U000F0937",
 | 
			
		||||
    "angle-obtuse": "\U000F0938",
 | 
			
		||||
@ -745,6 +749,7 @@ md_icons = {
 | 
			
		||||
    "arrow-up-thin": "\U000F19B2",
 | 
			
		||||
    "arrow-up-thin-circle-outline": "\U000F1597",
 | 
			
		||||
    "arrow-vertical-lock": "\U000F115C",
 | 
			
		||||
    "artboard": "\U000F1B9A",
 | 
			
		||||
    "artstation": "\U000F0B5B",
 | 
			
		||||
    "aspect-ratio": "\U000F0A24",
 | 
			
		||||
    "assistant": "\U000F0064",
 | 
			
		||||
@ -762,6 +767,7 @@ md_icons = {
 | 
			
		||||
    "attachment-off": "\U000F1AC3",
 | 
			
		||||
    "attachment-plus": "\U000F1AC4",
 | 
			
		||||
    "attachment-remove": "\U000F1AC5",
 | 
			
		||||
    "atv": "\U000F1B70",
 | 
			
		||||
    "audio-input-rca": "\U000F186B",
 | 
			
		||||
    "audio-input-stereo-minijack": "\U000F186C",
 | 
			
		||||
    "audio-input-xlr": "\U000F186D",
 | 
			
		||||
@ -774,6 +780,8 @@ md_icons = {
 | 
			
		||||
    "autorenew": "\U000F006A",
 | 
			
		||||
    "autorenew-off": "\U000F19E7",
 | 
			
		||||
    "av-timer": "\U000F006B",
 | 
			
		||||
    "awning": "\U000F1B87",
 | 
			
		||||
    "awning-outline": "\U000F1B88",
 | 
			
		||||
    "aws": "\U000F0E0F",
 | 
			
		||||
    "axe": "\U000F08C8",
 | 
			
		||||
    "axe-battle": "\U000F1842",
 | 
			
		||||
@ -987,6 +995,7 @@ md_icons = {
 | 
			
		||||
    "beaker-remove": "\U000F1233",
 | 
			
		||||
    "beaker-remove-outline": "\U000F1234",
 | 
			
		||||
    "bed": "\U000F02E3",
 | 
			
		||||
    "bed-clock": "\U000F1B94",
 | 
			
		||||
    "bed-double": "\U000F0FD4",
 | 
			
		||||
    "bed-double-outline": "\U000F0FD3",
 | 
			
		||||
    "bed-empty": "\U000F08A0",
 | 
			
		||||
@ -1148,10 +1157,11 @@ md_icons = {
 | 
			
		||||
    "book-sync": "\U000F169C",
 | 
			
		||||
    "book-sync-outline": "\U000F16C8",
 | 
			
		||||
    "book-variant": "\U000F00BF",
 | 
			
		||||
    "book-variant-multiple": "\U000F00BC",
 | 
			
		||||
    "bookmark": "\U000F00C0",
 | 
			
		||||
    "bookmark-box": "\U000F1B75",
 | 
			
		||||
    "bookmark-box-multiple": "\U000F196C",
 | 
			
		||||
    "bookmark-box-multiple-outline": "\U000F196D",
 | 
			
		||||
    "bookmark-box-outline": "\U000F1B76",
 | 
			
		||||
    "bookmark-check": "\U000F00C1",
 | 
			
		||||
    "bookmark-check-outline": "\U000F137B",
 | 
			
		||||
    "bookmark-minus": "\U000F09CC",
 | 
			
		||||
@ -1339,8 +1349,11 @@ md_icons = {
 | 
			
		||||
    "calendar-account": "\U000F0ED7",
 | 
			
		||||
    "calendar-account-outline": "\U000F0ED8",
 | 
			
		||||
    "calendar-alert": "\U000F0A31",
 | 
			
		||||
    "calendar-alert-outline": "\U000F1B62",
 | 
			
		||||
    "calendar-arrow-left": "\U000F1134",
 | 
			
		||||
    "calendar-arrow-right": "\U000F1135",
 | 
			
		||||
    "calendar-badge": "\U000F1B9D",
 | 
			
		||||
    "calendar-badge-outline": "\U000F1B9E",
 | 
			
		||||
    "calendar-blank": "\U000F00EE",
 | 
			
		||||
    "calendar-blank-multiple": "\U000F1073",
 | 
			
		||||
    "calendar-blank-outline": "\U000F0B66",
 | 
			
		||||
@ -1349,26 +1362,40 @@ md_icons = {
 | 
			
		||||
    "calendar-clock": "\U000F00F0",
 | 
			
		||||
    "calendar-clock-outline": "\U000F16E1",
 | 
			
		||||
    "calendar-collapse-horizontal": "\U000F189D",
 | 
			
		||||
    "calendar-collapse-horizontal-outline": "\U000F1B63",
 | 
			
		||||
    "calendar-cursor": "\U000F157B",
 | 
			
		||||
    "calendar-cursor-outline": "\U000F1B64",
 | 
			
		||||
    "calendar-edit": "\U000F08A7",
 | 
			
		||||
    "calendar-edit-outline": "\U000F1B65",
 | 
			
		||||
    "calendar-end": "\U000F166C",
 | 
			
		||||
    "calendar-end-outline": "\U000F1B66",
 | 
			
		||||
    "calendar-expand-horizontal": "\U000F189E",
 | 
			
		||||
    "calendar-expand-horizontal-outline": "\U000F1B67",
 | 
			
		||||
    "calendar-export": "\U000F0B24",
 | 
			
		||||
    "calendar-export-outline": "\U000F1B68",
 | 
			
		||||
    "calendar-filter": "\U000F1A32",
 | 
			
		||||
    "calendar-filter-outline": "\U000F1A33",
 | 
			
		||||
    "calendar-heart": "\U000F09D2",
 | 
			
		||||
    "calendar-heart-outline": "\U000F1B69",
 | 
			
		||||
    "calendar-import": "\U000F0B25",
 | 
			
		||||
    "calendar-import-outline": "\U000F1B6A",
 | 
			
		||||
    "calendar-lock": "\U000F1641",
 | 
			
		||||
    "calendar-lock-open": "\U000F1B5B",
 | 
			
		||||
    "calendar-lock-open-outline": "\U000F1B5C",
 | 
			
		||||
    "calendar-lock-outline": "\U000F1642",
 | 
			
		||||
    "calendar-minus": "\U000F0D5C",
 | 
			
		||||
    "calendar-minus-outline": "\U000F1B6B",
 | 
			
		||||
    "calendar-month": "\U000F0E17",
 | 
			
		||||
    "calendar-month-outline": "\U000F0E18",
 | 
			
		||||
    "calendar-multiple": "\U000F00F1",
 | 
			
		||||
    "calendar-multiple-check": "\U000F00F2",
 | 
			
		||||
    "calendar-multiselect": "\U000F0A32",
 | 
			
		||||
    "calendar-multiselect-outline": "\U000F1B55",
 | 
			
		||||
    "calendar-outline": "\U000F0B67",
 | 
			
		||||
    "calendar-plus": "\U000F00F3",
 | 
			
		||||
    "calendar-plus-outline": "\U000F1B6C",
 | 
			
		||||
    "calendar-question": "\U000F0692",
 | 
			
		||||
    "calendar-question-outline": "\U000F1B6D",
 | 
			
		||||
    "calendar-range": "\U000F0679",
 | 
			
		||||
    "calendar-range-outline": "\U000F0B68",
 | 
			
		||||
    "calendar-refresh": "\U000F01E1",
 | 
			
		||||
@ -1376,9 +1403,11 @@ md_icons = {
 | 
			
		||||
    "calendar-remove": "\U000F00F4",
 | 
			
		||||
    "calendar-remove-outline": "\U000F0C45",
 | 
			
		||||
    "calendar-search": "\U000F094C",
 | 
			
		||||
    "calendar-search-outline": "\U000F1B6E",
 | 
			
		||||
    "calendar-star": "\U000F09D3",
 | 
			
		||||
    "calendar-star-outline": "\U000F1B53",
 | 
			
		||||
    "calendar-start": "\U000F166D",
 | 
			
		||||
    "calendar-start-outline": "\U000F1B6F",
 | 
			
		||||
    "calendar-sync": "\U000F0E8E",
 | 
			
		||||
    "calendar-sync-outline": "\U000F0E8F",
 | 
			
		||||
    "calendar-text": "\U000F00F5",
 | 
			
		||||
@ -1496,6 +1525,8 @@ md_icons = {
 | 
			
		||||
    "car-outline": "\U000F14ED",
 | 
			
		||||
    "car-parking-lights": "\U000F0D63",
 | 
			
		||||
    "car-pickup": "\U000F07AA",
 | 
			
		||||
    "car-search": "\U000F1B8D",
 | 
			
		||||
    "car-search-outline": "\U000F1B8E",
 | 
			
		||||
    "car-seat": "\U000F0FA4",
 | 
			
		||||
    "car-seat-cooler": "\U000F0FA5",
 | 
			
		||||
    "car-seat-heater": "\U000F0FA6",
 | 
			
		||||
@ -1584,6 +1615,7 @@ md_icons = {
 | 
			
		||||
    "cart-minus": "\U000F0D68",
 | 
			
		||||
    "cart-off": "\U000F066B",
 | 
			
		||||
    "cart-outline": "\U000F0111",
 | 
			
		||||
    "cart-percent": "\U000F1BAE",
 | 
			
		||||
    "cart-plus": "\U000F0112",
 | 
			
		||||
    "cart-remove": "\U000F0D69",
 | 
			
		||||
    "cart-variant": "\U000F15EB",
 | 
			
		||||
@ -1969,6 +2001,7 @@ md_icons = {
 | 
			
		||||
    "cloud-tags": "\U000F07B6",
 | 
			
		||||
    "cloud-upload": "\U000F0167",
 | 
			
		||||
    "cloud-upload-outline": "\U000F0B7E",
 | 
			
		||||
    "clouds": "\U000F1B95",
 | 
			
		||||
    "clover": "\U000F0816",
 | 
			
		||||
    "coach-lamp": "\U000F1020",
 | 
			
		||||
    "coach-lamp-variant": "\U000F1A37",
 | 
			
		||||
@ -2128,8 +2161,10 @@ md_icons = {
 | 
			
		||||
    "contrast": "\U000F0195",
 | 
			
		||||
    "contrast-box": "\U000F0196",
 | 
			
		||||
    "contrast-circle": "\U000F0197",
 | 
			
		||||
    "controller": "\U000F02B4",
 | 
			
		||||
    "controller-classic": "\U000F0B82",
 | 
			
		||||
    "controller-classic-outline": "\U000F0B83",
 | 
			
		||||
    "controller-off": "\U000F02B5",
 | 
			
		||||
    "cookie": "\U000F0198",
 | 
			
		||||
    "cookie-alert": "\U000F16D0",
 | 
			
		||||
    "cookie-alert-outline": "\U000F16D1",
 | 
			
		||||
@ -2278,6 +2313,7 @@ md_icons = {
 | 
			
		||||
    "currency-sign": "\U000F07BE",
 | 
			
		||||
    "currency-try": "\U000F01B2",
 | 
			
		||||
    "currency-twd": "\U000F07BF",
 | 
			
		||||
    "currency-uah": "\U000F1B9B",
 | 
			
		||||
    "currency-usd": "\U000F01C1",
 | 
			
		||||
    "currency-usd-off": "\U000F067A",
 | 
			
		||||
    "current-ac": "\U000F1480",
 | 
			
		||||
@ -2391,8 +2427,6 @@ md_icons = {
 | 
			
		||||
    "desk-lamp-on": "\U000F1B20",
 | 
			
		||||
    "deskphone": "\U000F01C3",
 | 
			
		||||
    "desktop-classic": "\U000F07C0",
 | 
			
		||||
    "desktop-mac": "\U000F01C4",
 | 
			
		||||
    "desktop-mac-dashboard": "\U000F09E8",
 | 
			
		||||
    "desktop-tower": "\U000F01C5",
 | 
			
		||||
    "desktop-tower-monitor": "\U000F0AAB",
 | 
			
		||||
    "details": "\U000F01C6",
 | 
			
		||||
@ -2442,7 +2476,6 @@ md_icons = {
 | 
			
		||||
    "disc": "\U000F05EE",
 | 
			
		||||
    "disc-alert": "\U000F01D1",
 | 
			
		||||
    "disc-player": "\U000F0960",
 | 
			
		||||
    "discord": "\U000F066F",
 | 
			
		||||
    "dishwasher": "\U000F0AAC",
 | 
			
		||||
    "dishwasher-alert": "\U000F11B8",
 | 
			
		||||
    "dishwasher-off": "\U000F11B9",
 | 
			
		||||
@ -2457,8 +2490,9 @@ md_icons = {
 | 
			
		||||
    "diving": "\U000F1977",
 | 
			
		||||
    "diving-flippers": "\U000F0DBF",
 | 
			
		||||
    "diving-helmet": "\U000F0DC0",
 | 
			
		||||
    "diving-scuba": "\U000F0DC1",
 | 
			
		||||
    "diving-scuba": "\U000F1B77",
 | 
			
		||||
    "diving-scuba-flag": "\U000F0DC2",
 | 
			
		||||
    "diving-scuba-mask": "\U000F0DC1",
 | 
			
		||||
    "diving-scuba-tank": "\U000F0DC3",
 | 
			
		||||
    "diving-scuba-tank-multiple": "\U000F0DC4",
 | 
			
		||||
    "diving-snorkel": "\U000F0DC5",
 | 
			
		||||
@ -2590,6 +2624,10 @@ md_icons = {
 | 
			
		||||
    "email": "\U000F01EE",
 | 
			
		||||
    "email-alert": "\U000F06CF",
 | 
			
		||||
    "email-alert-outline": "\U000F0D42",
 | 
			
		||||
    "email-arrow-left": "\U000F10DA",
 | 
			
		||||
    "email-arrow-left-outline": "\U000F10DB",
 | 
			
		||||
    "email-arrow-right": "\U000F10DC",
 | 
			
		||||
    "email-arrow-right-outline": "\U000F10DD",
 | 
			
		||||
    "email-box": "\U000F0D03",
 | 
			
		||||
    "email-check": "\U000F0AB1",
 | 
			
		||||
    "email-check-outline": "\U000F0AB2",
 | 
			
		||||
@ -2598,6 +2636,7 @@ md_icons = {
 | 
			
		||||
    "email-fast": "\U000F186F",
 | 
			
		||||
    "email-fast-outline": "\U000F1870",
 | 
			
		||||
    "email-lock": "\U000F01F1",
 | 
			
		||||
    "email-lock-outline": "\U000F1B61",
 | 
			
		||||
    "email-mark-as-unread": "\U000F0B92",
 | 
			
		||||
    "email-minus": "\U000F0EE5",
 | 
			
		||||
    "email-minus-outline": "\U000F0EE6",
 | 
			
		||||
@ -2613,16 +2652,12 @@ md_icons = {
 | 
			
		||||
    "email-outline": "\U000F01F0",
 | 
			
		||||
    "email-plus": "\U000F09EB",
 | 
			
		||||
    "email-plus-outline": "\U000F09EC",
 | 
			
		||||
    "email-receive": "\U000F10DA",
 | 
			
		||||
    "email-receive-outline": "\U000F10DB",
 | 
			
		||||
    "email-remove": "\U000F1661",
 | 
			
		||||
    "email-remove-outline": "\U000F1662",
 | 
			
		||||
    "email-seal": "\U000F195B",
 | 
			
		||||
    "email-seal-outline": "\U000F195C",
 | 
			
		||||
    "email-search": "\U000F0961",
 | 
			
		||||
    "email-search-outline": "\U000F0962",
 | 
			
		||||
    "email-send": "\U000F10DC",
 | 
			
		||||
    "email-send-outline": "\U000F10DD",
 | 
			
		||||
    "email-sync": "\U000F12C7",
 | 
			
		||||
    "email-sync-outline": "\U000F12C8",
 | 
			
		||||
    "email-variant": "\U000F05F0",
 | 
			
		||||
@ -3013,7 +3048,15 @@ md_icons = {
 | 
			
		||||
    "flag-remove-outline": "\U000F10B4",
 | 
			
		||||
    "flag-triangle": "\U000F023F",
 | 
			
		||||
    "flag-variant": "\U000F0240",
 | 
			
		||||
    "flag-variant-minus": "\U000F1BB4",
 | 
			
		||||
    "flag-variant-minus-outline": "\U000F1BB5",
 | 
			
		||||
    "flag-variant-off": "\U000F1BB0",
 | 
			
		||||
    "flag-variant-off-outline": "\U000F1BB1",
 | 
			
		||||
    "flag-variant-outline": "\U000F023E",
 | 
			
		||||
    "flag-variant-plus": "\U000F1BB2",
 | 
			
		||||
    "flag-variant-plus-outline": "\U000F1BB3",
 | 
			
		||||
    "flag-variant-remove": "\U000F1BB6",
 | 
			
		||||
    "flag-variant-remove-outline": "\U000F1BB7",
 | 
			
		||||
    "flare": "\U000F0D72",
 | 
			
		||||
    "flash": "\U000F0241",
 | 
			
		||||
    "flash-alert": "\U000F0EF7",
 | 
			
		||||
@ -3275,6 +3318,7 @@ md_icons = {
 | 
			
		||||
    "format-list-checkbox": "\U000F096A",
 | 
			
		||||
    "format-list-checks": "\U000F0756",
 | 
			
		||||
    "format-list-group": "\U000F1860",
 | 
			
		||||
    "format-list-group-plus": "\U000F1B56",
 | 
			
		||||
    "format-list-numbered": "\U000F027B",
 | 
			
		||||
    "format-list-numbered-rtl": "\U000F0D0D",
 | 
			
		||||
    "format-list-text": "\U000F126F",
 | 
			
		||||
@ -3285,6 +3329,8 @@ md_icons = {
 | 
			
		||||
    "format-paragraph": "\U000F027D",
 | 
			
		||||
    "format-paragraph-spacing": "\U000F1AFD",
 | 
			
		||||
    "format-pilcrow": "\U000F06D8",
 | 
			
		||||
    "format-pilcrow-arrow-left": "\U000F0286",
 | 
			
		||||
    "format-pilcrow-arrow-right": "\U000F0285",
 | 
			
		||||
    "format-quote-close": "\U000F027E",
 | 
			
		||||
    "format-quote-close-outline": "\U000F11A8",
 | 
			
		||||
    "format-quote-open": "\U000F0757",
 | 
			
		||||
@ -3310,8 +3356,6 @@ md_icons = {
 | 
			
		||||
    "format-text-wrapping-overflow": "\U000F0D0F",
 | 
			
		||||
    "format-text-wrapping-wrap": "\U000F0D10",
 | 
			
		||||
    "format-textbox": "\U000F0D11",
 | 
			
		||||
    "format-textdirection-l-to-r": "\U000F0285",
 | 
			
		||||
    "format-textdirection-r-to-l": "\U000F0286",
 | 
			
		||||
    "format-title": "\U000F05F4",
 | 
			
		||||
    "format-underline": "\U000F0287",
 | 
			
		||||
    "format-underline-wavy": "\U000F18E9",
 | 
			
		||||
@ -3487,7 +3531,8 @@ md_icons = {
 | 
			
		||||
    "glass-tulip": "\U000F02A8",
 | 
			
		||||
    "glass-wine": "\U000F0876",
 | 
			
		||||
    "glasses": "\U000F02AA",
 | 
			
		||||
    "globe-light": "\U000F12D7",
 | 
			
		||||
    "globe-light": "\U000F066F",
 | 
			
		||||
    "globe-light-outline": "\U000F12D7",
 | 
			
		||||
    "globe-model": "\U000F08E9",
 | 
			
		||||
    "gmail": "\U000F02AB",
 | 
			
		||||
    "gnome": "\U000F02AC",
 | 
			
		||||
@ -3512,15 +3557,12 @@ md_icons = {
 | 
			
		||||
    "google-circles-group": "\U000F02B3",
 | 
			
		||||
    "google-classroom": "\U000F02C0",
 | 
			
		||||
    "google-cloud": "\U000F11F6",
 | 
			
		||||
    "google-controller": "\U000F02B4",
 | 
			
		||||
    "google-controller-off": "\U000F02B5",
 | 
			
		||||
    "google-downasaur": "\U000F1362",
 | 
			
		||||
    "google-drive": "\U000F02B6",
 | 
			
		||||
    "google-earth": "\U000F02B7",
 | 
			
		||||
    "google-fit": "\U000F096C",
 | 
			
		||||
    "google-glass": "\U000F02B8",
 | 
			
		||||
    "google-hangouts": "\U000F02C9",
 | 
			
		||||
    "google-home": "\U000F0824",
 | 
			
		||||
    "google-keep": "\U000F06DC",
 | 
			
		||||
    "google-lens": "\U000F09F6",
 | 
			
		||||
    "google-maps": "\U000F05F5",
 | 
			
		||||
@ -3582,6 +3624,7 @@ md_icons = {
 | 
			
		||||
    "hand-clap-off": "\U000F1A42",
 | 
			
		||||
    "hand-coin": "\U000F188F",
 | 
			
		||||
    "hand-coin-outline": "\U000F1890",
 | 
			
		||||
    "hand-cycle": "\U000F1B9C",
 | 
			
		||||
    "hand-extended": "\U000F18B6",
 | 
			
		||||
    "hand-extended-outline": "\U000F18B7",
 | 
			
		||||
    "hand-front-left": "\U000F182B",
 | 
			
		||||
@ -3615,6 +3658,7 @@ md_icons = {
 | 
			
		||||
    "harddisk-remove": "\U000F104C",
 | 
			
		||||
    "hat-fedora": "\U000F0BA4",
 | 
			
		||||
    "hazard-lights": "\U000F0C89",
 | 
			
		||||
    "hdmi-port": "\U000F1BB8",
 | 
			
		||||
    "hdr": "\U000F0D7D",
 | 
			
		||||
    "hdr-off": "\U000F0D7E",
 | 
			
		||||
    "head": "\U000F135E",
 | 
			
		||||
@ -3768,6 +3812,8 @@ md_icons = {
 | 
			
		||||
    "home-roof": "\U000F112B",
 | 
			
		||||
    "home-search": "\U000F13B0",
 | 
			
		||||
    "home-search-outline": "\U000F13B1",
 | 
			
		||||
    "home-silo": "\U000F1BA0",
 | 
			
		||||
    "home-silo-outline": "\U000F1BA1",
 | 
			
		||||
    "home-switch": "\U000F1794",
 | 
			
		||||
    "home-switch-outline": "\U000F1795",
 | 
			
		||||
    "home-thermometer": "\U000F0F54",
 | 
			
		||||
@ -3827,6 +3873,7 @@ md_icons = {
 | 
			
		||||
    "human-pregnant": "\U000F05CF",
 | 
			
		||||
    "human-queue": "\U000F1571",
 | 
			
		||||
    "human-scooter": "\U000F11E9",
 | 
			
		||||
    "human-walker": "\U000F1B71",
 | 
			
		||||
    "human-wheelchair": "\U000F138D",
 | 
			
		||||
    "human-white-cane": "\U000F1981",
 | 
			
		||||
    "humble-bundle": "\U000F0744",
 | 
			
		||||
@ -4005,6 +4052,7 @@ md_icons = {
 | 
			
		||||
    "klingon": "\U000F135B",
 | 
			
		||||
    "knife": "\U000F09FB",
 | 
			
		||||
    "knife-military": "\U000F09FC",
 | 
			
		||||
    "knob": "\U000F1B96",
 | 
			
		||||
    "koala": "\U000F173F",
 | 
			
		||||
    "kodi": "\U000F0314",
 | 
			
		||||
    "kubernetes": "\U000F10FE",
 | 
			
		||||
@ -4092,7 +4140,7 @@ md_icons = {
 | 
			
		||||
    "leaf-off": "\U000F12D9",
 | 
			
		||||
    "leak": "\U000F0DD7",
 | 
			
		||||
    "leak-off": "\U000F0DD8",
 | 
			
		||||
    "lecturn": "\U000F1AF0",
 | 
			
		||||
    "lectern": "\U000F1AF0",
 | 
			
		||||
    "led-off": "\U000F032B",
 | 
			
		||||
    "led-on": "\U000F032C",
 | 
			
		||||
    "led-outline": "\U000F032D",
 | 
			
		||||
@ -4182,6 +4230,8 @@ md_icons = {
 | 
			
		||||
    "lipstick": "\U000F13B5",
 | 
			
		||||
    "liquid-spot": "\U000F1826",
 | 
			
		||||
    "liquor": "\U000F191E",
 | 
			
		||||
    "list-box": "\U000F1B7B",
 | 
			
		||||
    "list-box-outline": "\U000F1B7C",
 | 
			
		||||
    "list-status": "\U000F15AB",
 | 
			
		||||
    "litecoin": "\U000F0A61",
 | 
			
		||||
    "loading": "\U000F0772",
 | 
			
		||||
@ -4362,6 +4412,8 @@ md_icons = {
 | 
			
		||||
    "message-bookmark-outline": "\U000F15AD",
 | 
			
		||||
    "message-bulleted": "\U000F06A2",
 | 
			
		||||
    "message-bulleted-off": "\U000F06A3",
 | 
			
		||||
    "message-check": "\U000F1B8A",
 | 
			
		||||
    "message-check-outline": "\U000F1B8B",
 | 
			
		||||
    "message-cog": "\U000F06F1",
 | 
			
		||||
    "message-cog-outline": "\U000F1172",
 | 
			
		||||
    "message-draw": "\U000F0363",
 | 
			
		||||
@ -4410,6 +4462,8 @@ md_icons = {
 | 
			
		||||
    "metronome-tick": "\U000F07DB",
 | 
			
		||||
    "micro-sd": "\U000F07DC",
 | 
			
		||||
    "microphone": "\U000F036C",
 | 
			
		||||
    "microphone-message": "\U000F050A",
 | 
			
		||||
    "microphone-message-off": "\U000F050B",
 | 
			
		||||
    "microphone-minus": "\U000F08B3",
 | 
			
		||||
    "microphone-off": "\U000F036D",
 | 
			
		||||
    "microphone-outline": "\U000F036E",
 | 
			
		||||
@ -4519,7 +4573,8 @@ md_icons = {
 | 
			
		||||
    "more": "\U000F037B",
 | 
			
		||||
    "mortar-pestle": "\U000F1748",
 | 
			
		||||
    "mortar-pestle-plus": "\U000F03F1",
 | 
			
		||||
    "mosque": "\U000F1827",
 | 
			
		||||
    "mosque": "\U000F0D45",
 | 
			
		||||
    "mosque-outline": "\U000F1827",
 | 
			
		||||
    "mother-heart": "\U000F1314",
 | 
			
		||||
    "mother-nurse": "\U000F0D21",
 | 
			
		||||
    "motion": "\U000F15B2",
 | 
			
		||||
@ -4594,8 +4649,11 @@ md_icons = {
 | 
			
		||||
    "movie-star-outline": "\U000F1718",
 | 
			
		||||
    "mower": "\U000F166F",
 | 
			
		||||
    "mower-bag": "\U000F1670",
 | 
			
		||||
    "mower-bag-on": "\U000F1B60",
 | 
			
		||||
    "mower-on": "\U000F1B5F",
 | 
			
		||||
    "muffin": "\U000F098C",
 | 
			
		||||
    "multicast": "\U000F1893",
 | 
			
		||||
    "multimedia": "\U000F1B97",
 | 
			
		||||
    "multiplication": "\U000F0382",
 | 
			
		||||
    "multiplication-box": "\U000F0383",
 | 
			
		||||
    "mushroom": "\U000F07DF",
 | 
			
		||||
@ -4624,6 +4682,7 @@ md_icons = {
 | 
			
		||||
    "music-note-eighth-dotted": "\U000F0F71",
 | 
			
		||||
    "music-note-half": "\U000F0389",
 | 
			
		||||
    "music-note-half-dotted": "\U000F0F72",
 | 
			
		||||
    "music-note-minus": "\U000F1B89",
 | 
			
		||||
    "music-note-off": "\U000F038A",
 | 
			
		||||
    "music-note-off-outline": "\U000F0F73",
 | 
			
		||||
    "music-note-outline": "\U000F0F74",
 | 
			
		||||
@ -4846,7 +4905,13 @@ md_icons = {
 | 
			
		||||
    "office-building-cog-outline": "\U000F194A",
 | 
			
		||||
    "office-building-marker": "\U000F1520",
 | 
			
		||||
    "office-building-marker-outline": "\U000F1521",
 | 
			
		||||
    "office-building-minus": "\U000F1BAA",
 | 
			
		||||
    "office-building-minus-outline": "\U000F1BAB",
 | 
			
		||||
    "office-building-outline": "\U000F151F",
 | 
			
		||||
    "office-building-plus": "\U000F1BA8",
 | 
			
		||||
    "office-building-plus-outline": "\U000F1BA9",
 | 
			
		||||
    "office-building-remove": "\U000F1BAC",
 | 
			
		||||
    "office-building-remove-outline": "\U000F1BAD",
 | 
			
		||||
    "oil": "\U000F03C7",
 | 
			
		||||
    "oil-lamp": "\U000F0F19",
 | 
			
		||||
    "oil-level": "\U000F1053",
 | 
			
		||||
@ -4967,6 +5032,8 @@ md_icons = {
 | 
			
		||||
    "patio-heater": "\U000F0F80",
 | 
			
		||||
    "patreon": "\U000F0882",
 | 
			
		||||
    "pause": "\U000F03E4",
 | 
			
		||||
    "pause-box": "\U000F00BC",
 | 
			
		||||
    "pause-box-outline": "\U000F1B7A",
 | 
			
		||||
    "pause-circle": "\U000F03E5",
 | 
			
		||||
    "pause-circle-outline": "\U000F03E6",
 | 
			
		||||
    "pause-octagon": "\U000F03E7",
 | 
			
		||||
@ -5253,6 +5320,7 @@ md_icons = {
 | 
			
		||||
    "progress-clock": "\U000F0996",
 | 
			
		||||
    "progress-close": "\U000F110A",
 | 
			
		||||
    "progress-download": "\U000F0997",
 | 
			
		||||
    "progress-helper": "\U000F1BA2",
 | 
			
		||||
    "progress-pencil": "\U000F1787",
 | 
			
		||||
    "progress-question": "\U000F1522",
 | 
			
		||||
    "progress-star": "\U000F1788",
 | 
			
		||||
@ -5351,12 +5419,14 @@ md_icons = {
 | 
			
		||||
    "razor-single-edge": "\U000F1998",
 | 
			
		||||
    "react": "\U000F0708",
 | 
			
		||||
    "read": "\U000F0447",
 | 
			
		||||
    "receipt": "\U000F0449",
 | 
			
		||||
    "receipt-outline": "\U000F19DC",
 | 
			
		||||
    "receipt": "\U000F0824",
 | 
			
		||||
    "receipt-outline": "\U000F04F7",
 | 
			
		||||
    "receipt-text": "\U000F0449",
 | 
			
		||||
    "receipt-text-check": "\U000F1A63",
 | 
			
		||||
    "receipt-text-check-outline": "\U000F1A64",
 | 
			
		||||
    "receipt-text-minus": "\U000F1A65",
 | 
			
		||||
    "receipt-text-minus-outline": "\U000F1A66",
 | 
			
		||||
    "receipt-text-outline": "\U000F19DC",
 | 
			
		||||
    "receipt-text-plus": "\U000F1A67",
 | 
			
		||||
    "receipt-text-plus-outline": "\U000F1A68",
 | 
			
		||||
    "receipt-text-remove": "\U000F1A69",
 | 
			
		||||
@ -5495,7 +5565,9 @@ md_icons = {
 | 
			
		||||
    "robot-off-outline": "\U000F167B",
 | 
			
		||||
    "robot-outline": "\U000F167A",
 | 
			
		||||
    "robot-vacuum": "\U000F070D",
 | 
			
		||||
    "robot-vacuum-alert": "\U000F1B5D",
 | 
			
		||||
    "robot-vacuum-variant": "\U000F0908",
 | 
			
		||||
    "robot-vacuum-variant-alert": "\U000F1B5E",
 | 
			
		||||
    "rocket": "\U000F0463",
 | 
			
		||||
    "rocket-launch": "\U000F14DE",
 | 
			
		||||
    "rocket-launch-outline": "\U000F14DF",
 | 
			
		||||
@ -5633,6 +5705,8 @@ md_icons = {
 | 
			
		||||
    "segment": "\U000F0ECB",
 | 
			
		||||
    "select": "\U000F0485",
 | 
			
		||||
    "select-all": "\U000F0486",
 | 
			
		||||
    "select-arrow-down": "\U000F1B59",
 | 
			
		||||
    "select-arrow-up": "\U000F1B58",
 | 
			
		||||
    "select-color": "\U000F0D31",
 | 
			
		||||
    "select-compare": "\U000F0AD9",
 | 
			
		||||
    "select-drag": "\U000F0A6C",
 | 
			
		||||
@ -5803,6 +5877,7 @@ md_icons = {
 | 
			
		||||
    "sign-pole": "\U000F14F8",
 | 
			
		||||
    "sign-real-estate": "\U000F1118",
 | 
			
		||||
    "sign-text": "\U000F0782",
 | 
			
		||||
    "sign-yield": "\U000F1BAF",
 | 
			
		||||
    "signal": "\U000F04A2",
 | 
			
		||||
    "signal-2g": "\U000F0712",
 | 
			
		||||
    "signal-3g": "\U000F0713",
 | 
			
		||||
@ -5821,7 +5896,8 @@ md_icons = {
 | 
			
		||||
    "signature-freehand": "\U000F0DFC",
 | 
			
		||||
    "signature-image": "\U000F0DFD",
 | 
			
		||||
    "signature-text": "\U000F0DFE",
 | 
			
		||||
    "silo": "\U000F0B49",
 | 
			
		||||
    "silo": "\U000F1B9F",
 | 
			
		||||
    "silo-outline": "\U000F0B49",
 | 
			
		||||
    "silverware": "\U000F04A3",
 | 
			
		||||
    "silverware-clean": "\U000F0FDE",
 | 
			
		||||
    "silverware-fork": "\U000F04A4",
 | 
			
		||||
@ -6000,6 +6076,9 @@ md_icons = {
 | 
			
		||||
    "speaker-message": "\U000F1B11",
 | 
			
		||||
    "speaker-multiple": "\U000F0D38",
 | 
			
		||||
    "speaker-off": "\U000F04C4",
 | 
			
		||||
    "speaker-pause": "\U000F1B73",
 | 
			
		||||
    "speaker-play": "\U000F1B72",
 | 
			
		||||
    "speaker-stop": "\U000F1B74",
 | 
			
		||||
    "speaker-wireless": "\U000F071F",
 | 
			
		||||
    "spear": "\U000F1845",
 | 
			
		||||
    "speedometer": "\U000F04C5",
 | 
			
		||||
@ -6149,7 +6228,17 @@ md_icons = {
 | 
			
		||||
    "store-settings": "\U000F18D4",
 | 
			
		||||
    "store-settings-outline": "\U000F18D5",
 | 
			
		||||
    "storefront": "\U000F07C7",
 | 
			
		||||
    "storefront-check": "\U000F1B7D",
 | 
			
		||||
    "storefront-check-outline": "\U000F1B7E",
 | 
			
		||||
    "storefront-edit": "\U000F1B7F",
 | 
			
		||||
    "storefront-edit-outline": "\U000F1B80",
 | 
			
		||||
    "storefront-minus": "\U000F1B83",
 | 
			
		||||
    "storefront-minus-outline": "\U000F1B84",
 | 
			
		||||
    "storefront-outline": "\U000F10C1",
 | 
			
		||||
    "storefront-plus": "\U000F1B81",
 | 
			
		||||
    "storefront-plus-outline": "\U000F1B82",
 | 
			
		||||
    "storefront-remove": "\U000F1B85",
 | 
			
		||||
    "storefront-remove-outline": "\U000F1B86",
 | 
			
		||||
    "stove": "\U000F04DE",
 | 
			
		||||
    "strategy": "\U000F11D6",
 | 
			
		||||
    "stretch-to-page": "\U000F0F2B",
 | 
			
		||||
@ -6239,6 +6328,7 @@ md_icons = {
 | 
			
		||||
    "table-edit": "\U000F04F0",
 | 
			
		||||
    "table-eye": "\U000F1094",
 | 
			
		||||
    "table-eye-off": "\U000F13C3",
 | 
			
		||||
    "table-filter": "\U000F1B8C",
 | 
			
		||||
    "table-furniture": "\U000F05BC",
 | 
			
		||||
    "table-headers-eye": "\U000F121D",
 | 
			
		||||
    "table-headers-eye-off": "\U000F121E",
 | 
			
		||||
@ -6272,7 +6362,6 @@ md_icons = {
 | 
			
		||||
    "table-sync": "\U000F13A1",
 | 
			
		||||
    "table-tennis": "\U000F0E68",
 | 
			
		||||
    "tablet": "\U000F04F6",
 | 
			
		||||
    "tablet-android": "\U000F04F7",
 | 
			
		||||
    "tablet-cellphone": "\U000F09A7",
 | 
			
		||||
    "tablet-dashboard": "\U000F0ECE",
 | 
			
		||||
    "taco": "\U000F0762",
 | 
			
		||||
@ -6377,8 +6466,6 @@ md_icons = {
 | 
			
		||||
    "text-search-variant": "\U000F1A7E",
 | 
			
		||||
    "text-shadow": "\U000F0669",
 | 
			
		||||
    "text-short": "\U000F09A9",
 | 
			
		||||
    "text-to-speech": "\U000F050A",
 | 
			
		||||
    "text-to-speech-off": "\U000F050B",
 | 
			
		||||
    "texture": "\U000F050C",
 | 
			
		||||
    "texture-box": "\U000F0FE6",
 | 
			
		||||
    "theater": "\U000F050D",
 | 
			
		||||
@ -6429,13 +6516,13 @@ md_icons = {
 | 
			
		||||
    "timeline-check-outline": "\U000F1533",
 | 
			
		||||
    "timeline-clock": "\U000F11FB",
 | 
			
		||||
    "timeline-clock-outline": "\U000F11FC",
 | 
			
		||||
    "timeline-help": "\U000F0F99",
 | 
			
		||||
    "timeline-help-outline": "\U000F0F9A",
 | 
			
		||||
    "timeline-minus": "\U000F1534",
 | 
			
		||||
    "timeline-minus-outline": "\U000F1535",
 | 
			
		||||
    "timeline-outline": "\U000F0BD2",
 | 
			
		||||
    "timeline-plus": "\U000F0F96",
 | 
			
		||||
    "timeline-plus-outline": "\U000F0F97",
 | 
			
		||||
    "timeline-question": "\U000F0F99",
 | 
			
		||||
    "timeline-question-outline": "\U000F0F9A",
 | 
			
		||||
    "timeline-remove": "\U000F1536",
 | 
			
		||||
    "timeline-remove-outline": "\U000F1537",
 | 
			
		||||
    "timeline-text": "\U000F0BD3",
 | 
			
		||||
@ -6601,6 +6688,7 @@ md_icons = {
 | 
			
		||||
    "transition-masked": "\U000F0916",
 | 
			
		||||
    "translate": "\U000F05CA",
 | 
			
		||||
    "translate-off": "\U000F0E06",
 | 
			
		||||
    "translate-variant": "\U000F1B99",
 | 
			
		||||
    "transmission-tower": "\U000F0D3E",
 | 
			
		||||
    "transmission-tower-export": "\U000F192C",
 | 
			
		||||
    "transmission-tower-import": "\U000F192D",
 | 
			
		||||
@ -6744,7 +6832,11 @@ md_icons = {
 | 
			
		||||
    "vector-intersection": "\U000F055D",
 | 
			
		||||
    "vector-line": "\U000F055E",
 | 
			
		||||
    "vector-link": "\U000F0FE8",
 | 
			
		||||
    "vector-point": "\U000F055F",
 | 
			
		||||
    "vector-point": "\U000F01C4",
 | 
			
		||||
    "vector-point-edit": "\U000F09E8",
 | 
			
		||||
    "vector-point-minus": "\U000F1B78",
 | 
			
		||||
    "vector-point-plus": "\U000F1B79",
 | 
			
		||||
    "vector-point-select": "\U000F055F",
 | 
			
		||||
    "vector-polygon": "\U000F0560",
 | 
			
		||||
    "vector-polygon-variant": "\U000F1856",
 | 
			
		||||
    "vector-polyline": "\U000F0561",
 | 
			
		||||
@ -6912,6 +7004,7 @@ md_icons = {
 | 
			
		||||
    "water-alert-outline": "\U000F1503",
 | 
			
		||||
    "water-boiler": "\U000F0F92",
 | 
			
		||||
    "water-boiler-alert": "\U000F11B3",
 | 
			
		||||
    "water-boiler-auto": "\U000F1B98",
 | 
			
		||||
    "water-boiler-off": "\U000F11B4",
 | 
			
		||||
    "water-check": "\U000F1504",
 | 
			
		||||
    "water-check-outline": "\U000F1505",
 | 
			
		||||
@ -6951,6 +7044,7 @@ md_icons = {
 | 
			
		||||
    "weather-cloudy-alert": "\U000F0F2F",
 | 
			
		||||
    "weather-cloudy-arrow-right": "\U000F0E6E",
 | 
			
		||||
    "weather-cloudy-clock": "\U000F18F6",
 | 
			
		||||
    "weather-dust": "\U000F1B5A",
 | 
			
		||||
    "weather-fog": "\U000F0591",
 | 
			
		||||
    "weather-hail": "\U000F0592",
 | 
			
		||||
    "weather-hazy": "\U000F0F30",
 | 
			
		||||
@ -7072,6 +7166,7 @@ md_icons = {
 | 
			
		||||
    "window-restore": "\U000F05B2",
 | 
			
		||||
    "window-shutter": "\U000F111C",
 | 
			
		||||
    "window-shutter-alert": "\U000F111D",
 | 
			
		||||
    "window-shutter-auto": "\U000F1BA3",
 | 
			
		||||
    "window-shutter-cog": "\U000F1A8A",
 | 
			
		||||
    "window-shutter-open": "\U000F111E",
 | 
			
		||||
    "window-shutter-settings": "\U000F1A8B",
 | 
			
		||||
@ -7084,7 +7179,12 @@ md_icons = {
 | 
			
		||||
    "wrap": "\U000F05B6",
 | 
			
		||||
    "wrap-disabled": "\U000F0BDF",
 | 
			
		||||
    "wrench": "\U000F05B7",
 | 
			
		||||
    "wrench-check": "\U000F1B8F",
 | 
			
		||||
    "wrench-check-outline": "\U000F1B90",
 | 
			
		||||
    "wrench-clock": "\U000F19A3",
 | 
			
		||||
    "wrench-clock-outline": "\U000F1B93",
 | 
			
		||||
    "wrench-cog": "\U000F1B91",
 | 
			
		||||
    "wrench-cog-outline": "\U000F1B92",
 | 
			
		||||
    "wrench-outline": "\U000F0BE0",
 | 
			
		||||
    "xamarin": "\U000F0845",
 | 
			
		||||
    "xml": "\U000F05C0",
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 5.3 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								sbapp/kivymd/images/logo/kivymd-icon-128.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 19 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								sbapp/kivymd/images/logo/kivymd-icon-256.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 31 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								sbapp/kivymd/images/logo/kivymd-icon-512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 53 KiB  | 
| 
		 Before Width: | Height: | Size: 31 KiB  | 
| 
		 Before Width: | Height: | Size: 31 KiB  | 
| 
		 Before Width: | Height: | Size: 21 KiB  | 
@ -1 +0,0 @@
 | 
			
		||||
{"quad_shadow-1.png": {"20": [2, 136, 128, 128], "21": [132, 136, 128, 128], "22": [262, 136, 128, 128], "23": [2, 6, 128, 128], "19": [132, 266, 128, 128], "18": [2, 266, 128, 128], "1": [262, 266, 128, 128], "3": [262, 6, 128, 128], "2": [132, 6, 128, 128]}, "quad_shadow-0.png": {"11": [262, 266, 128, 128], "10": [132, 266, 128, 128], "13": [132, 136, 128, 128], "12": [2, 136, 128, 128], "15": [2, 6, 128, 128], "14": [262, 136, 128, 128], "17": [262, 6, 128, 128], "16": [132, 6, 128, 128], "0": [2, 266, 128, 128]}, "quad_shadow-2.png": {"5": [132, 266, 128, 128], "4": [2, 266, 128, 128], "7": [2, 136, 128, 128], "6": [262, 266, 128, 128], "9": [262, 136, 128, 128], "8": [132, 136, 128, 128]}}
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 46 KiB  | 
| 
		 Before Width: | Height: | Size: 43 KiB  | 
@ -1 +0,0 @@
 | 
			
		||||
{"rec_shadow-1.png": {"20": [2, 266, 256, 128], "21": [260, 266, 256, 128], "22": [518, 266, 256, 128], "23": [776, 266, 256, 128], "3": [260, 136, 256, 128], "2": [2, 136, 256, 128], "5": [776, 136, 256, 128], "4": [518, 136, 256, 128], "7": [260, 6, 256, 128], "6": [2, 6, 256, 128], "9": [776, 6, 256, 128], "8": [518, 6, 256, 128]}, "rec_shadow-0.png": {"11": [518, 266, 256, 128], "10": [260, 266, 256, 128], "13": [2, 136, 256, 128], "12": [776, 266, 256, 128], "15": [518, 136, 256, 128], "14": [260, 136, 256, 128], "17": [2, 6, 256, 128], "16": [776, 136, 256, 128], "19": [518, 6, 256, 128], "18": [260, 6, 256, 128], "1": [776, 6, 256, 128], "0": [2, 266, 256, 128]}}
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 30 KiB  | 
| 
		 Before Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 28 KiB  | 
@ -1 +0,0 @@
 | 
			
		||||
{"rec_st_shadow-0.png": {"11": [262, 138, 128, 256], "10": [132, 138, 128, 256], "13": [522, 138, 128, 256], "12": [392, 138, 128, 256], "15": [782, 138, 128, 256], "14": [652, 138, 128, 256], "16": [912, 138, 128, 256], "0": [2, 138, 128, 256]}, "rec_st_shadow-1.png": {"20": [522, 138, 128, 256], "21": [652, 138, 128, 256], "17": [2, 138, 128, 256], "23": [912, 138, 128, 256], "19": [262, 138, 128, 256], "18": [132, 138, 128, 256], "22": [782, 138, 128, 256], "1": [392, 138, 128, 256]}, "rec_st_shadow-2.png": {"3": [132, 138, 128, 256], "2": [2, 138, 128, 256], "5": [392, 138, 128, 256], "4": [262, 138, 128, 256], "7": [652, 138, 128, 256], "6": [522, 138, 128, 256], "9": [912, 138, 128, 256], "8": [782, 138, 128, 256]}}
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 15 KiB  | 
| 
		 Before Width: | Height: | Size: 39 KiB  | 
| 
		 Before Width: | Height: | Size: 40 KiB  | 
| 
		 Before Width: | Height: | Size: 26 KiB  | 
@ -1 +0,0 @@
 | 
			
		||||
{"round_shadow-1.png": {"20": [2, 136, 128, 128], "21": [132, 136, 128, 128], "22": [262, 136, 128, 128], "23": [2, 6, 128, 128], "19": [132, 266, 128, 128], "18": [2, 266, 128, 128], "1": [262, 266, 128, 128], "3": [262, 6, 128, 128], "2": [132, 6, 128, 128]}, "round_shadow-0.png": {"11": [262, 266, 128, 128], "10": [132, 266, 128, 128], "13": [132, 136, 128, 128], "12": [2, 136, 128, 128], "15": [2, 6, 128, 128], "14": [262, 136, 128, 128], "17": [262, 6, 128, 128], "16": [132, 6, 128, 128], "0": [2, 266, 128, 128]}, "round_shadow-2.png": {"5": [132, 266, 128, 128], "4": [2, 266, 128, 128], "7": [2, 136, 128, 128], "6": [262, 266, 128, 128], "9": [262, 136, 128, 128], "8": [132, 136, 128, 128]}}
 | 
			
		||||
							
								
								
									
										9
									
								
								sbapp/kivymd/tests/base_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,9 @@
 | 
			
		||||
from kivy.tests.common import GraphicUnitTest
 | 
			
		||||
 | 
			
		||||
from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseTest(GraphicUnitTest):
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.app = MDApp()  # NOQA
 | 
			
		||||
@ -35,8 +35,15 @@ assert "Icons" in LabelBase._fonts.keys()  # NOQA
 | 
			
		||||
 | 
			
		||||
images = os.listdir(kivymd.images_path)
 | 
			
		||||
print(images)
 | 
			
		||||
assert "logo" in images
 | 
			
		||||
assert "alpha_layer.png" in images
 | 
			
		||||
assert "black.png" in images
 | 
			
		||||
assert "blue.png" in images
 | 
			
		||||
assert "red.png" in images
 | 
			
		||||
assert "green.png" in images
 | 
			
		||||
assert "yellow.png" in images
 | 
			
		||||
assert "folder.png" in images
 | 
			
		||||
assert "rec_shadow.atlas" in images
 | 
			
		||||
assert "transparent.png" in images
 | 
			
		||||
"""
 | 
			
		||||
    )
 | 
			
		||||
    pyi_main.run(
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								sbapp/kivymd/tests/test_backdrop.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,24 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BackdropTest(BaseTest):
 | 
			
		||||
    def test_backdrop_raw_app(self):
 | 
			
		||||
        from kivymd.uix.backdrop import MDBackdrop
 | 
			
		||||
        from kivymd.uix.backdrop.backdrop import (
 | 
			
		||||
            MDBackdropBackLayer,
 | 
			
		||||
            MDBackdropFrontLayer,
 | 
			
		||||
        )
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
        from kivymd.uix.widget import MDWidget
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDBackdrop(
 | 
			
		||||
                    MDBackdropBackLayer(MDWidget()),
 | 
			
		||||
                    MDBackdropFrontLayer(MDWidget()),
 | 
			
		||||
                    id="backdrop",
 | 
			
		||||
                    title="Example Backdrop",
 | 
			
		||||
                    header_text="Menu:",
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										32
									
								
								sbapp/kivymd/tests/test_bottom_navigation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,32 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BottomNavigationTest(BaseTest):
 | 
			
		||||
    def test_bottom_navigation_m3_style_raw_app(self):
 | 
			
		||||
        from kivymd.uix.bottomnavigation import (
 | 
			
		||||
            MDBottomNavigation,
 | 
			
		||||
            MDBottomNavigationItem,
 | 
			
		||||
        )
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
        self.app.theme_cls.material_style = "M3"
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDBottomNavigation(
 | 
			
		||||
                    MDBottomNavigationItem(
 | 
			
		||||
                        name="screen 1",
 | 
			
		||||
                        text="Mail",
 | 
			
		||||
                        icon="gmail",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDBottomNavigationItem(
 | 
			
		||||
                        name="screen 2",
 | 
			
		||||
                        text="Twitter",
 | 
			
		||||
                        icon="twitter",
 | 
			
		||||
                        badge_icon="numeric-10",
 | 
			
		||||
                    ),
 | 
			
		||||
                    panel_color="#eeeaea",
 | 
			
		||||
                    selected_color_background="#97ecf8",
 | 
			
		||||
                    text_color_active="red",
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										25
									
								
								sbapp/kivymd/tests/test_card.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,25 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CardTest(BaseTest):
 | 
			
		||||
    def test_card_m3_style_raw_app(self):
 | 
			
		||||
        from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
 | 
			
		||||
        from kivymd.uix.card import MDCard
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
        class MD3Card(MDCard, RoundedRectangularElevationBehavior):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        self.app.theme_cls.material_style = "M3"
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MD3Card(
 | 
			
		||||
                    size_hint=(None, None),
 | 
			
		||||
                    pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                    size=("200dp", "100dp"),
 | 
			
		||||
                    line_color=(0.2, 0.2, 0.2, 0.8),
 | 
			
		||||
                    style="elevated",
 | 
			
		||||
                    md_bg_color="lightblue",
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										16
									
								
								sbapp/kivymd/tests/test_chip.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ChipTest(BaseTest):
 | 
			
		||||
    def test_chip_raw_app(self):
 | 
			
		||||
        from kivymd.uix.chip import MDChip
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDChip(
 | 
			
		||||
                    text="Portland",
 | 
			
		||||
                    pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
@ -1,14 +1,13 @@
 | 
			
		||||
def test_create_project():
 | 
			
		||||
    import os
 | 
			
		||||
    import sys
 | 
			
		||||
 | 
			
		||||
    os.system(
 | 
			
		||||
        f"{sys.executable} -m kivymd.tools.patterns.create_project "
 | 
			
		||||
        f"python3.10 -m kivymd.tools.patterns.create_project "
 | 
			
		||||
        f"MVC "
 | 
			
		||||
        f"{os.path.expanduser('~')} "
 | 
			
		||||
        f"TestProject "
 | 
			
		||||
        f"{sys.executable} "
 | 
			
		||||
        f"master "
 | 
			
		||||
        f"python3.10 "
 | 
			
		||||
        f"stable "
 | 
			
		||||
        f"--name_screen TestProjectScreen "
 | 
			
		||||
        f"--name_database restdb "
 | 
			
		||||
        f"--use_hotreload yes"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								sbapp/kivymd/tests/test_fitimage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,24 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FitImageTest(BaseTest):
 | 
			
		||||
    def test_fitimage_raw_app(self):
 | 
			
		||||
        import os
 | 
			
		||||
 | 
			
		||||
        from kivymd import images_path
 | 
			
		||||
        from kivymd.uix.fitimage import FitImage
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                FitImage(
 | 
			
		||||
                    source=os.path.join(
 | 
			
		||||
                        images_path, "logo", "kivymd-icon-512.png"
 | 
			
		||||
                    ),
 | 
			
		||||
                    size_hint=(0.5, 0.5),
 | 
			
		||||
                    pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                    radius=[36, 36, 0, 0],
 | 
			
		||||
                    mipmap=True,
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										39
									
								
								sbapp/kivymd/tests/test_imagelist.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,39 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ImageListTest(BaseTest):
 | 
			
		||||
    def test_imagelist_raw_app(self):
 | 
			
		||||
        import os
 | 
			
		||||
 | 
			
		||||
        from kivymd import images_path
 | 
			
		||||
        from kivymd.uix.button import MDIconButton
 | 
			
		||||
        from kivymd.uix.imagelist import MDSmartTile
 | 
			
		||||
        from kivymd.uix.label import MDLabel
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDSmartTile(
 | 
			
		||||
                    MDIconButton(
 | 
			
		||||
                        icon="heart-outline",
 | 
			
		||||
                        theme_icon_color="Custom",
 | 
			
		||||
                        icon_color="red",
 | 
			
		||||
                        pos_hint={"center_y": 0.5},
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDLabel(
 | 
			
		||||
                        text="Julia and Julie",
 | 
			
		||||
                        bold=True,
 | 
			
		||||
                        color="white",
 | 
			
		||||
                    ),
 | 
			
		||||
                    radius=24,
 | 
			
		||||
                    box_radius=[0, 0, 24, 24],
 | 
			
		||||
                    box_color="grey",
 | 
			
		||||
                    source=os.path.join(
 | 
			
		||||
                        images_path, "logo", "kivymd-icon-512.png"
 | 
			
		||||
                    ),
 | 
			
		||||
                    pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                    size_hint=(None, None),
 | 
			
		||||
                    size=("320dp", "320dp"),
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										67
									
								
								sbapp/kivymd/tests/test_list.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,67 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListTest(BaseTest):
 | 
			
		||||
    def test_list_raw_app(self):
 | 
			
		||||
        import os
 | 
			
		||||
 | 
			
		||||
        from kivymd import images_path
 | 
			
		||||
        from kivymd.uix.list import (
 | 
			
		||||
            IconLeftWidget,
 | 
			
		||||
            IconRightWidget,
 | 
			
		||||
            ImageLeftWidget,
 | 
			
		||||
            IRightBodyTouch,
 | 
			
		||||
            MDList,
 | 
			
		||||
            OneLineAvatarIconListItem,
 | 
			
		||||
            OneLineAvatarListItem,
 | 
			
		||||
            OneLineIconListItem,
 | 
			
		||||
            OneLineListItem,
 | 
			
		||||
            ThreeLineListItem,
 | 
			
		||||
            TwoLineListItem,
 | 
			
		||||
        )
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
        from kivymd.uix.scrollview import MDScrollView
 | 
			
		||||
        from kivymd.uix.selectioncontrol import MDCheckbox
 | 
			
		||||
 | 
			
		||||
        class RightCheckbox(IRightBodyTouch, MDCheckbox):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDScrollView(
 | 
			
		||||
                    MDList(
 | 
			
		||||
                        OneLineListItem(text="Text"),
 | 
			
		||||
                        TwoLineListItem(
 | 
			
		||||
                            text="Text", secondary_text="secondary text"
 | 
			
		||||
                        ),
 | 
			
		||||
                        ThreeLineListItem(
 | 
			
		||||
                            text="Text",
 | 
			
		||||
                            secondary_text="secondary text",
 | 
			
		||||
                            tertiary_text="tertiary text",
 | 
			
		||||
                        ),
 | 
			
		||||
                        OneLineAvatarListItem(
 | 
			
		||||
                            ImageLeftWidget(
 | 
			
		||||
                                source=os.path.join(
 | 
			
		||||
                                    images_path, "logo", "kivymd-icon-512.png"
 | 
			
		||||
                                )
 | 
			
		||||
                            ),
 | 
			
		||||
                            text="Text",
 | 
			
		||||
                        ),
 | 
			
		||||
                        OneLineIconListItem(
 | 
			
		||||
                            IconLeftWidget(icon="plus"),
 | 
			
		||||
                            text="Text",
 | 
			
		||||
                        ),
 | 
			
		||||
                        OneLineAvatarIconListItem(
 | 
			
		||||
                            IconLeftWidget(icon="plus"),
 | 
			
		||||
                            IconRightWidget(icon="minus"),
 | 
			
		||||
                            text="Text",
 | 
			
		||||
                        ),
 | 
			
		||||
                        OneLineAvatarIconListItem(
 | 
			
		||||
                            IconLeftWidget(icon="plus"),
 | 
			
		||||
                            RightCheckbox(),
 | 
			
		||||
                            text="Text",
 | 
			
		||||
                        ),
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										94
									
								
								sbapp/kivymd/tests/test_navigationdrawer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,94 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NavigationDrawerTest(BaseTest):
 | 
			
		||||
    def test_navigationdrawer_raw_app(self):
 | 
			
		||||
        from kivymd.uix.navigationdrawer import (
 | 
			
		||||
            MDNavigationDrawer,
 | 
			
		||||
            MDNavigationDrawerDivider,
 | 
			
		||||
            MDNavigationDrawerHeader,
 | 
			
		||||
            MDNavigationDrawerItem,
 | 
			
		||||
            MDNavigationDrawerLabel,
 | 
			
		||||
            MDNavigationDrawerMenu,
 | 
			
		||||
            MDNavigationLayout,
 | 
			
		||||
        )
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
        from kivymd.uix.screenmanager import MDScreenManager
 | 
			
		||||
        from kivymd.uix.toolbar import MDTopAppBar
 | 
			
		||||
 | 
			
		||||
        class DrawerClickableItem(MDNavigationDrawerItem):
 | 
			
		||||
            def __init__(self, **kwargs):
 | 
			
		||||
                super().__init__(**kwargs)
 | 
			
		||||
                self.focus_color = "#e7e4c0"
 | 
			
		||||
                self.unfocus_color = "#f7f4e7"
 | 
			
		||||
                self.text_color = "#4a4939"
 | 
			
		||||
                self.icon_color = "#4a4939"
 | 
			
		||||
                self.ripple_color = "#c5bdd2"
 | 
			
		||||
                self.selected_color = "#0c6c4d"
 | 
			
		||||
 | 
			
		||||
        class DrawerLabelItem(MDNavigationDrawerItem):
 | 
			
		||||
            def __init__(self, **kwargs):
 | 
			
		||||
                super().__init__(**kwargs)
 | 
			
		||||
                self.bg_color = "#f7f4e7"
 | 
			
		||||
                self.text_color = "#4a4939"
 | 
			
		||||
                self.icon_color = "#4a4939"
 | 
			
		||||
                _no_ripple_effect = True  # NOQA
 | 
			
		||||
 | 
			
		||||
        self.app.theme_cls.material_style = "M3"
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDNavigationLayout(
 | 
			
		||||
                MDScreenManager(
 | 
			
		||||
                    MDScreen(
 | 
			
		||||
                        MDTopAppBar(
 | 
			
		||||
                            title="Navigation Drawer",
 | 
			
		||||
                            elevation=10,
 | 
			
		||||
                            pos_hint={"top": 1},
 | 
			
		||||
                            md_bg_color="#e7e4c0",
 | 
			
		||||
                            specific_text_color="#4a4939",
 | 
			
		||||
                            left_action_items=[
 | 
			
		||||
                                ["menu", lambda x: self.nav_drawer_open()]
 | 
			
		||||
                            ],
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                ),
 | 
			
		||||
                MDNavigationDrawer(
 | 
			
		||||
                    MDNavigationDrawerMenu(
 | 
			
		||||
                        MDNavigationDrawerHeader(
 | 
			
		||||
                            title="Header title",
 | 
			
		||||
                            title_color="#4a4939",
 | 
			
		||||
                            text="Header text",
 | 
			
		||||
                            spacing="4dp",
 | 
			
		||||
                            padding=("12dp", 0, 0, "56dp"),
 | 
			
		||||
                        ),
 | 
			
		||||
                        MDNavigationDrawerLabel(
 | 
			
		||||
                            text="Mail",
 | 
			
		||||
                        ),
 | 
			
		||||
                        DrawerClickableItem(
 | 
			
		||||
                            icon="gmail",
 | 
			
		||||
                            right_text="+99",
 | 
			
		||||
                            text_right_color="#4a4939",
 | 
			
		||||
                            text="Inbox",
 | 
			
		||||
                            radius=24,
 | 
			
		||||
                        ),
 | 
			
		||||
                        DrawerClickableItem(
 | 
			
		||||
                            icon="send",
 | 
			
		||||
                            text="Outbox",
 | 
			
		||||
                            radius=24,
 | 
			
		||||
                        ),
 | 
			
		||||
                        MDNavigationDrawerDivider(),
 | 
			
		||||
                        MDNavigationDrawerLabel(
 | 
			
		||||
                            text="Labels",
 | 
			
		||||
                        ),
 | 
			
		||||
                        DrawerLabelItem(
 | 
			
		||||
                            icon="information-outline",
 | 
			
		||||
                            text="Label",
 | 
			
		||||
                        ),
 | 
			
		||||
                        DrawerLabelItem(
 | 
			
		||||
                            icon="information-outline",
 | 
			
		||||
                            text="Label",
 | 
			
		||||
                        ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    id="nav_drawer",
 | 
			
		||||
                ),
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
							
								
								
									
										14
									
								
								sbapp/kivymd/tests/test_tab.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,14 @@
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TabTest(BaseTest):
 | 
			
		||||
    def test_tab_raw_app(self):
 | 
			
		||||
        from kivymd.uix.floatlayout import MDFloatLayout
 | 
			
		||||
        from kivymd.uix.tab import MDTabs, MDTabsBase
 | 
			
		||||
 | 
			
		||||
        class Tab(MDFloatLayout, MDTabsBase):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        tab = MDTabs()
 | 
			
		||||
        tab.add_widget(Tab(title="Tab"))
 | 
			
		||||
        self.render(tab)
 | 
			
		||||
							
								
								
									
										72
									
								
								sbapp/kivymd/tests/test_textfield.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,72 @@
 | 
			
		||||
# from kivy.clock import Clock
 | 
			
		||||
# from kivy.uix.textinput import TextInput
 | 
			
		||||
 | 
			
		||||
from kivymd.tests.base_test import BaseTest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TextFieldTest(BaseTest):
 | 
			
		||||
    def test_textfield_raw_app(self):
 | 
			
		||||
        from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
        from kivymd.uix.button import MDFlatButton
 | 
			
		||||
        from kivymd.uix.screen import MDScreen
 | 
			
		||||
        from kivymd.uix.textfield import MDTextField
 | 
			
		||||
 | 
			
		||||
        # def set_text():
 | 
			
		||||
        #     for widget in self.screen.ids.box.children:
 | 
			
		||||
        #         if issubclass(widget.__class__, TextInput):
 | 
			
		||||
        #             widget.text = "Input text"
 | 
			
		||||
 | 
			
		||||
        self.render(
 | 
			
		||||
            MDScreen(
 | 
			
		||||
                MDBoxLayout(
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                        mode="rectangle",
 | 
			
		||||
                        max_text_length=5,
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        icon_left="git",
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                        mode="rectangle",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        icon_left="git",
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                        mode="fill",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                        mode="fill",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        icon_left="git",
 | 
			
		||||
                        hint_text="Label",
 | 
			
		||||
                        helper_text="Error massage",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDTextField(
 | 
			
		||||
                        hint_text="Round mode",
 | 
			
		||||
                        mode="round",
 | 
			
		||||
                        max_text_length=15,
 | 
			
		||||
                        helper_text="Massage",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDFlatButton(
 | 
			
		||||
                        text="SET TEXT",
 | 
			
		||||
                        pos_hint={"center_x": 0.5},
 | 
			
		||||
                    ),
 | 
			
		||||
                    id="box",
 | 
			
		||||
                    orientation="vertical",
 | 
			
		||||
                    spacing="20dp",
 | 
			
		||||
                    adaptive_height=True,
 | 
			
		||||
                    size_hint_x=0.8,
 | 
			
		||||
                    pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
@ -298,8 +298,9 @@ class MDApp(BaseApp):
 | 
			
		||||
        from kivy.core.window import Window
 | 
			
		||||
        from kivy.utils import get_color_from_hex
 | 
			
		||||
 | 
			
		||||
        Window.clearcolor = get_color_from_hex("#e50000")
 | 
			
		||||
        scroll = Factory.ScrollView(scroll_y=0)
 | 
			
		||||
        scroll = Factory.MDScrollView(
 | 
			
		||||
            scroll_y=0, md_bg_color=get_color_from_hex("#e50000")
 | 
			
		||||
        )
 | 
			
		||||
        lbl = Factory.Label(
 | 
			
		||||
            text_size=(Window.width - 100, None),
 | 
			
		||||
            size_hint_y=None,
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,18 @@ from pathlib import Path
 | 
			
		||||
import kivymd
 | 
			
		||||
 | 
			
		||||
datas = [
 | 
			
		||||
    # Add `.frag` files from the `kivymd/data/glsl/elevation` directory.
 | 
			
		||||
    (
 | 
			
		||||
        str(Path(kivymd.glsl_path).joinpath("elevation")) + os.sep,
 | 
			
		||||
        str(
 | 
			
		||||
            Path("kivymd").joinpath(
 | 
			
		||||
                str(Path(kivymd.glsl_path)).split(str(Path("kivymd")) + os.sep)[
 | 
			
		||||
                    1
 | 
			
		||||
                ]
 | 
			
		||||
                + f"{os.sep}elevation"
 | 
			
		||||
            )
 | 
			
		||||
        ),
 | 
			
		||||
    ),
 | 
			
		||||
    # Add `.ttf` files from the `kivymd/fonts` directory.
 | 
			
		||||
    (
 | 
			
		||||
        kivymd.fonts_path,
 | 
			
		||||
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
%s
 | 
			
		||||
    def get_view(self) -> %s:
 | 
			
		||||
        return self.view
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
# FILE TO FIND AND CREATE LOCALIZATION FILES FOR YOUR APPLICATION. \
 | 
			
		||||
\
 | 
			
		||||
In this file, you can specify in which files of your project to search for \
 | 
			
		||||
localization strings. \
 | 
			
		||||
These files should be listed in the below command: \
 | 
			
		||||
\
 | 
			
		||||
\
 | 
			
		||||
xgettext -Lpython --output=messages.pot --from-code=utf-8 \
 | 
			
		||||
    path/to/file-1 \
 | 
			
		||||
    path/to/file-2 \
 | 
			
		||||
    ...
 | 
			
		||||
 | 
			
		||||
.PHONY: po mo
 | 
			
		||||
 | 
			
		||||
po:
 | 
			
		||||
	xgettext -Lpython --output=messages.pot --from-code=utf-8 \
 | 
			
		||||
             View/%s/%s.kv \
 | 
			
		||||
             View/%s/%s.py
 | 
			
		||||
	msgmerge --update --no-fuzzy-matching --backup=off data/locales/po/en.po messages.pot
 | 
			
		||||
	msgmerge --update --no-fuzzy-matching --backup=off data/locales/po/ru.po messages.pot
 | 
			
		||||
 | 
			
		||||
mo:
 | 
			
		||||
	mkdir -p data/locales/en/LC_MESSAGES
 | 
			
		||||
	mkdir -p data/locales/ru/LC_MESSAGES
 | 
			
		||||
	msgfmt -c -o data/locales/en/LC_MESSAGES/%s.mo data/locales/po/en.po
 | 
			
		||||
	msgfmt -c -o data/locales/ru/LC_MESSAGES/%s.mo data/locales/po/ru.po
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
# The model implements the observer pattern. This means that the class must
 | 
			
		||||
# support adding, removing, and alerting observers. In this case, the model is
 | 
			
		||||
# completely independent of controllers and views. It is important that all
 | 
			
		||||
# registered observers implement a specific method that will be called by the
 | 
			
		||||
# model when they are notified (in this case, it is the `model_is_changed`
 | 
			
		||||
# method). For this, observers must be descendants of an abstract class,
 | 
			
		||||
# inheriting which, the `model_is_changed` method must be overridden.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseScreenModel:
 | 
			
		||||
    """Implements a base class for model modules."""
 | 
			
		||||
 | 
			
		||||
    _observers = []
 | 
			
		||||
 | 
			
		||||
    def add_observer(self, observer) -> None:
 | 
			
		||||
        self._observers.append(observer)
 | 
			
		||||
 | 
			
		||||
    def remove_observer(self, observer) -> None:
 | 
			
		||||
        self._observers.remove(observer)
 | 
			
		||||
 | 
			
		||||
    def notify_observers(self, name_screen: str) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Method that will be called by the observer when the model data changes.
 | 
			
		||||
 | 
			
		||||
        :param name_screen:
 | 
			
		||||
            name of the view for which the method should be called
 | 
			
		||||
            :meth:`model_is_changed`.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        for observer in self._observers:
 | 
			
		||||
            if observer.name == name_screen:
 | 
			
		||||
                observer.model_is_changed()
 | 
			
		||||
                break
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
%s
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
# Of course, "very flexible Python" allows you to do without an abstract
 | 
			
		||||
# superclass at all or use the clever exception `NotImplementedError`. In my
 | 
			
		||||
# opinion, this can negatively affect the architecture of the application.
 | 
			
		||||
# I would like to point out that using Kivy, one could use the on-signaling
 | 
			
		||||
# model. In this case, when the state changes, the model will send a signal
 | 
			
		||||
# that can be received by all attached observers. This approach seems less
 | 
			
		||||
# universal - you may want to use a different library in the future.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Observer:
 | 
			
		||||
    """Abstract superclass for all observers."""
 | 
			
		||||
 | 
			
		||||
    def model_is_changed(self):
 | 
			
		||||
        """
 | 
			
		||||
        The method that will be called on the observer when the model changes.
 | 
			
		||||
        """
 | 
			
		||||
@ -1,72 +0,0 @@
 | 
			
		||||
#:import images_path kivymd.images_path
 | 
			
		||||
#:import colors kivymd.color_definitions.colors
 | 
			
		||||
#:import get_color_from_hex kivy.utils.get_color_from_hex
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<%s>
 | 
			
		||||
 | 
			
		||||
    FitImage:
 | 
			
		||||
        source:
 | 
			
		||||
            ( \
 | 
			
		||||
            f"{images_path}restdb-logo.png" \
 | 
			
		||||
            if root.model.database.name == "RestDB" else \
 | 
			
		||||
            f"{images_path}firebase-logo.png" \
 | 
			
		||||
            ) \
 | 
			
		||||
            if hasattr(root.model, "database") else \
 | 
			
		||||
            f"{images_path}transparent.png"
 | 
			
		||||
 | 
			
		||||
    MDBoxLayout:
 | 
			
		||||
        orientation: "vertical"
 | 
			
		||||
 | 
			
		||||
        MDToolbar:
 | 
			
		||||
            id: toolbar
 | 
			
		||||
            title: "%s"
 | 
			
		||||
            right_action_items: [["web", lambda x: %s]]
 | 
			
		||||
            md_bg_color:
 | 
			
		||||
                ( \
 | 
			
		||||
                get_color_from_hex(colors["Yellow"]["700"]) \
 | 
			
		||||
                if root.model.database.name == "Firebase" else \
 | 
			
		||||
                get_color_from_hex(colors["Blue"]["300"]) \
 | 
			
		||||
                ) \
 | 
			
		||||
                if hasattr(root.model, "database") else \
 | 
			
		||||
                app.theme_cls.primary_color
 | 
			
		||||
 | 
			
		||||
        MDFloatLayout:
 | 
			
		||||
 | 
			
		||||
            MDBoxLayout:
 | 
			
		||||
                orientation: "vertical"
 | 
			
		||||
                adaptive_height: True
 | 
			
		||||
                size_hint_x: None
 | 
			
		||||
                width: root.width - dp(72)
 | 
			
		||||
                radius: 12
 | 
			
		||||
                padding: "12dp"
 | 
			
		||||
                md_bg_color: 1, 1, 1, .5
 | 
			
		||||
                pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    id: prev_label
 | 
			
		||||
                    text: %s
 | 
			
		||||
                    font_style: "H6"
 | 
			
		||||
                    adaptive_height: True
 | 
			
		||||
                    halign: "center"
 | 
			
		||||
                    color: 1, 1, 1, 1
 | 
			
		||||
 | 
			
		||||
                MDBoxLayout:
 | 
			
		||||
                    orientation: "vertical"
 | 
			
		||||
                    adaptive_height: True
 | 
			
		||||
                    padding: "50dp"
 | 
			
		||||
                    spacing: "20dp"
 | 
			
		||||
 | 
			
		||||
                    MDTextField:
 | 
			
		||||
                        hint_text: %s
 | 
			
		||||
                        on_text: root.controller.set_user_data("login", self.text)
 | 
			
		||||
 | 
			
		||||
                    MDTextField:
 | 
			
		||||
                        hint_text: %s
 | 
			
		||||
                        on_text: root.controller.set_user_data("password", self.text)
 | 
			
		||||
 | 
			
		||||
    MDFillRoundFlatButton:
 | 
			
		||||
        text: %s
 | 
			
		||||
        on_release: root.controller.on_tap_button_login()
 | 
			
		||||
        pos_hint: {"center_x": .5, "center_y": .1}
 | 
			
		||||
        md_bg_color: toolbar.md_bg_color
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
%s
 | 
			
		||||
from View.base_screen import BaseScreenView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class %s(BaseScreenView):
 | 
			
		||||
    """Implements the login start screen in the user application."""
 | 
			
		||||
%s
 | 
			
		||||
    def model_is_changed(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Called whenever any change has occurred in the data model.
 | 
			
		||||
        The view in this method tracks these changes and updates the UI
 | 
			
		||||
        according to these changes.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        %s
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
from kivy.properties import ObjectProperty
 | 
			
		||||
 | 
			
		||||
from kivymd.app import MDApp
 | 
			
		||||
from kivymd.theming import ThemableBehavior
 | 
			
		||||
from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
from Utility.observer import Observer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseScreenView(ThemableBehavior, MDScreen, Observer):
 | 
			
		||||
    """
 | 
			
		||||
    A base class that implements a visual representation of the model data
 | 
			
		||||
    :class:`~Model.%s.%s`.
 | 
			
		||||
    The view class must be inherited from this class.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    controller = ObjectProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Controller object - :class:`~Controller.%s.%s`.
 | 
			
		||||
 | 
			
		||||
    :attr:`controller` is an :class:`~kivy.properties.ObjectProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    model = ObjectProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Model object - :class:`~Model.%s.%s`.
 | 
			
		||||
 | 
			
		||||
    :attr:`model` is an :class:`~kivy.properties.ObjectProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    manager_screens = ObjectProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Screen manager object - :class:`~kivy.uix.screenmanager.ScreenManager`.
 | 
			
		||||
 | 
			
		||||
    :attr:`manager_screens` is an :class:`~kivy.properties.ObjectProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kw):
 | 
			
		||||
        super().__init__(**kw)
 | 
			
		||||
        # Often you need to get access to the application object from the view
 | 
			
		||||
        # class. You can do this using this attribute.
 | 
			
		||||
        self.app = MDApp.get_running_app()
 | 
			
		||||
        # Adding a view class as observer.
 | 
			
		||||
        self.model.add_observer(self)
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
# The screens dictionary contains the objects of the models and controllers
 | 
			
		||||
# of the screens of the application.
 | 
			
		||||
 | 
			
		||||
from Model.%s import %s
 | 
			
		||||
 | 
			
		||||
from Controller.%s import %s
 | 
			
		||||
 | 
			
		||||
screens = {
 | 
			
		||||
    %s: {
 | 
			
		||||
        "model": %s,
 | 
			
		||||
        "controller": %s,
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
"""
 | 
			
		||||
The entry point to the application.
 | 
			
		||||
 | 
			
		||||
The application uses the MVC template. Adhering to the principles of clean
 | 
			
		||||
architecture means ensuring that your application is easy to test, maintain,
 | 
			
		||||
and modernize.
 | 
			
		||||
 | 
			
		||||
You can read more about this template at the links below:
 | 
			
		||||
 | 
			
		||||
https://github.com/HeaTTheatR/LoginAppMVC
 | 
			
		||||
https://en.wikipedia.org/wiki/Model–view–controller
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from typing import NoReturn
 | 
			
		||||
 | 
			
		||||
from kivy.uix.screenmanager import ScreenManager%s
 | 
			
		||||
 | 
			
		||||
from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
from View.screens import screens%s
 | 
			
		||||
%s
 | 
			
		||||
 | 
			
		||||
class %s(MDApp):%s
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)%s
 | 
			
		||||
        self.load_all_kv_files(self.directory)
 | 
			
		||||
        # This is the screen manager that will contain all the screens of your
 | 
			
		||||
        # application.
 | 
			
		||||
        self.manager_screens = ScreenManager()
 | 
			
		||||
        %s
 | 
			
		||||
    def build(self) -> ScreenManager:
 | 
			
		||||
        self.generate_application_screens()
 | 
			
		||||
        return self.manager_screens
 | 
			
		||||
 | 
			
		||||
    def generate_application_screens(self) -> NoReturn:
 | 
			
		||||
        """
 | 
			
		||||
        Creating and adding screens to the screen manager.
 | 
			
		||||
        You should not change this cycle unnecessarily. He is self-sufficient.
 | 
			
		||||
 | 
			
		||||
        If you need to add any screen, open the `View.screens.py` module and
 | 
			
		||||
        see how new screens are added according to the given application
 | 
			
		||||
        architecture.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        for i, name_screen in enumerate(screens.keys()):
 | 
			
		||||
            model = screens[name_screen]["model"](%s)
 | 
			
		||||
            controller = screens[name_screen]["controller"](model)
 | 
			
		||||
            view = controller.get_view()
 | 
			
		||||
            view.manager_screens = self.manager_screens
 | 
			
		||||
            view.name = name_screen
 | 
			
		||||
            self.manager_screens.add_widget(view)
 | 
			
		||||
%s%s
 | 
			
		||||
 | 
			
		||||
%s().run()
 | 
			
		||||
							
								
								
									
										210
									
								
								sbapp/kivymd/tools/patterns/add_view.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,210 @@
 | 
			
		||||
"""
 | 
			
		||||
The script creates a new View package
 | 
			
		||||
=====================================
 | 
			
		||||
 | 
			
		||||
The script creates a new View package in an existing project with an MVC
 | 
			
		||||
template created using the create_project utility.
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
.. seealso::
 | 
			
		||||
 | 
			
		||||
    `Utility create_project <https://kivymd.readthedocs.io/en/latest/api/kivymd/tools/patterns/create_project/>`_
 | 
			
		||||
 | 
			
		||||
.. rubric:: Use a clean architecture for your applications.
 | 
			
		||||
 | 
			
		||||
To add a new view to an existing project that was created using the
 | 
			
		||||
`create_project` utility, use the following command::
 | 
			
		||||
 | 
			
		||||
    kivymd.add_view \\
 | 
			
		||||
        name_pattern \\
 | 
			
		||||
        path_to_project \\
 | 
			
		||||
        name_view
 | 
			
		||||
 | 
			
		||||
Example command::
 | 
			
		||||
 | 
			
		||||
    kivymd.add_view \\
 | 
			
		||||
        MVC \\
 | 
			
		||||
        /Users/macbookair/Projects \\
 | 
			
		||||
        NewScreen
 | 
			
		||||
 | 
			
		||||
You can also add new views with responsive behavior to an existing project::
 | 
			
		||||
 | 
			
		||||
    kivymd.add_view \\
 | 
			
		||||
        MVC \\
 | 
			
		||||
        /Users/macbookair/Projects \\
 | 
			
		||||
        NewScreen \\
 | 
			
		||||
        --use_responsive yes
 | 
			
		||||
 | 
			
		||||
For more information about adaptive design,
 | 
			
		||||
`see here <https://kivymd.readthedocs.io/en/latest/components/responsivelayout/>`_.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = [
 | 
			
		||||
    "main",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from kivy import Logger
 | 
			
		||||
 | 
			
		||||
from kivymd.tools.argument_parser import ArgumentParserWithHelp
 | 
			
		||||
from kivymd.tools.patterns.create_project import (
 | 
			
		||||
    chek_camel_case_name_project,
 | 
			
		||||
    create_common_responsive_module,
 | 
			
		||||
    create_controller,
 | 
			
		||||
    create_model,
 | 
			
		||||
    create_view,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
screens_data = """%s
 | 
			
		||||
 | 
			
		||||
screens = {%s
 | 
			
		||||
}"""
 | 
			
		||||
 | 
			
		||||
screns_comment = """# The screen's dictionary contains the objects of the models and controllers
 | 
			
		||||
# of the screens of the application.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    """The function of adding a new view to the project."""
 | 
			
		||||
 | 
			
		||||
    global screens_data
 | 
			
		||||
 | 
			
		||||
    parser = create_argument_parser()
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    # pattern_name isn't used currently, will be used if new patterns is added in future
 | 
			
		||||
    pattern_name = args.pattern  # noqa F841
 | 
			
		||||
    path_to_project = args.directory
 | 
			
		||||
    name_view = args.name
 | 
			
		||||
    use_responsive = args.use_responsive
 | 
			
		||||
 | 
			
		||||
    if not os.path.exists(path_to_project):
 | 
			
		||||
        parser.error(f"Project <{path_to_project}> does not exist...")
 | 
			
		||||
 | 
			
		||||
    if name_view[-6:] != "Screen":
 | 
			
		||||
        parser.error(
 | 
			
		||||
            f"The name of the <{name_view}> screen should contain the word "
 | 
			
		||||
            f"'Screen' at the end.\n"
 | 
			
		||||
            "For example - '--name_screen MyFirstScreen ...'"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if name_view in os.listdir(os.path.join(path_to_project, "View")):
 | 
			
		||||
        parser.error(
 | 
			
		||||
            f"The <{name_view}> view also exists in the <{path_to_project}> project..."
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    # Create model.
 | 
			
		||||
    name_database = (
 | 
			
		||||
        "yes"
 | 
			
		||||
        if "database.py" in os.listdir(os.path.join(path_to_project, "Model"))
 | 
			
		||||
        else "no"
 | 
			
		||||
    )
 | 
			
		||||
    module_name = chek_camel_case_name_project(name_view)
 | 
			
		||||
    if not module_name:
 | 
			
		||||
        parser.error(
 | 
			
		||||
            "The name of the screen should be written in camel case style. "
 | 
			
		||||
            "\nFor example - 'MyFirstScreen'"
 | 
			
		||||
        )
 | 
			
		||||
    module_name = "_".join([name.lower() for name in module_name])
 | 
			
		||||
    path_to_project = path_to_project
 | 
			
		||||
    create_model(name_view, module_name, name_database, path_to_project)
 | 
			
		||||
 | 
			
		||||
    # Create controller.
 | 
			
		||||
    # FIXME: This is not a very good solution in order to understand whether
 | 
			
		||||
    #  a project uses a hot reload or not. Because the string
 | 
			
		||||
    #  'from kivymd.tools.hotreload.app import MDApp' in the project can just
 | 
			
		||||
    #  be commented out and the project does not actually use hot reload.
 | 
			
		||||
    with open(os.path.join(path_to_project, "main.py")) as main_module:
 | 
			
		||||
        if "from kivymd.tools.hotreload.app import MDApp" in main_module.read():
 | 
			
		||||
            use_hotreload = "yes"
 | 
			
		||||
        else:
 | 
			
		||||
            use_hotreload = "no"
 | 
			
		||||
        create_controller(
 | 
			
		||||
            name_view, module_name, use_hotreload, path_to_project
 | 
			
		||||
        )
 | 
			
		||||
    # Create View.
 | 
			
		||||
    if use_responsive == "no":
 | 
			
		||||
        create_view(name_view, module_name, [], path_to_project)
 | 
			
		||||
    else:
 | 
			
		||||
        create_view(name_view, module_name, [name_view], path_to_project)
 | 
			
		||||
        create_common_responsive_module([name_view], path_to_project)
 | 
			
		||||
    # Create 'View.screens.py module'.
 | 
			
		||||
    create_screens_data(name_view, module_name, path_to_project)
 | 
			
		||||
    Logger.info(
 | 
			
		||||
        f"KivyMD: The {name_view} view has been added to the project..."
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_screens_data(
 | 
			
		||||
    name_view: str, module_name: str, path_to_project: str
 | 
			
		||||
) -> None:
 | 
			
		||||
    with open(
 | 
			
		||||
        os.path.join(path_to_project, "View", "screens.py")
 | 
			
		||||
    ) as screen_module:
 | 
			
		||||
        screen_module = screen_module.read()
 | 
			
		||||
        imports = re.findall(
 | 
			
		||||
            "from Model.*Model|from Controller.*Controller", screen_module
 | 
			
		||||
        )
 | 
			
		||||
        screens = ""
 | 
			
		||||
        path_to_view = os.path.join(path_to_project, "View")
 | 
			
		||||
 | 
			
		||||
        for name in os.listdir(path_to_view):
 | 
			
		||||
            if os.path.isdir(os.path.join(path_to_view, name)):
 | 
			
		||||
                res = re.findall("[A-Z][a-z]*", name)
 | 
			
		||||
                if res and len(res) == 2 and res[-1] == "Screen":
 | 
			
		||||
                    screens += (
 | 
			
		||||
                        "\n    '%s': {"
 | 
			
		||||
                        "\n        'model': %s,"
 | 
			
		||||
                        "\n        'controller': %s,"
 | 
			
		||||
                        "\n    },"
 | 
			
		||||
                        % (
 | 
			
		||||
                            f"{res[0].lower()} {res[1].lower()}",
 | 
			
		||||
                            f'{"".join(res)}Model',
 | 
			
		||||
                            f'{"".join(res)}Controller',
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
        imports.append(f"from Model.{module_name} import {name_view}Model")
 | 
			
		||||
        imports.append(
 | 
			
		||||
            f"from Controller.{module_name} import {name_view}Controller"
 | 
			
		||||
        )
 | 
			
		||||
        imports.insert(0, screns_comment)
 | 
			
		||||
        screens = screens_data % ("\n".join(imports), screens)
 | 
			
		||||
 | 
			
		||||
        with open(
 | 
			
		||||
            os.path.join(path_to_project, "View", "screens.py"), "w"
 | 
			
		||||
        ) as screen_module:
 | 
			
		||||
            screen_module.write(screens)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_argument_parser() -> ArgumentParserWithHelp:
 | 
			
		||||
    parser = ArgumentParserWithHelp(
 | 
			
		||||
        prog="create_project.py",
 | 
			
		||||
        allow_abbrev=False,
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "pattern",
 | 
			
		||||
        help="the name of the pattern with which the project will be created.",
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "directory",
 | 
			
		||||
        help="the directory of the project to which you want to add a new view.",
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "name",
 | 
			
		||||
        help="the name of the view to add to an existing project.",
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--use_responsive",
 | 
			
		||||
        default="no",
 | 
			
		||||
        help="whether to create a view with responsive behavior.",
 | 
			
		||||
    )
 | 
			
		||||
    return parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Copyright (c) 2019-2021 Artem Bulgakov
 | 
			
		||||
# Copyright (c) 2019-2022 Artem Bulgakov
 | 
			
		||||
#
 | 
			
		||||
# This file is distributed under the terms of the same license,
 | 
			
		||||
# as the Kivy framework.
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Copyright (c) 2019-2021 Artem Bulgakov
 | 
			
		||||
# Copyright (c) 2019-2022 Artem Bulgakov
 | 
			
		||||
#
 | 
			
		||||
# This file is distributed under the terms of the same license,
 | 
			
		||||
# as the Kivy framework.
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Copyright (c) 2019-2021 Artem Bulgakov
 | 
			
		||||
# Copyright (c) 2019-2022 Artem Bulgakov
 | 
			
		||||
#
 | 
			
		||||
# This file is distributed under the terms of the same license,
 | 
			
		||||
# as the Kivy framework.
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ with some widget properties. For example:
 | 
			
		||||
AnchorLayout
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
.. code-block::
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    AnchorLayout:
 | 
			
		||||
        canvas:
 | 
			
		||||
@ -20,65 +20,13 @@ AnchorLayout
 | 
			
		||||
                pos: self.pos
 | 
			
		||||
                size: self.size
 | 
			
		||||
 | 
			
		||||
AnchorLayout
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
.. code-block::
 | 
			
		||||
 | 
			
		||||
    MDBoxLayout:
 | 
			
		||||
        md_bg_color: app.theme_cls.primary_color
 | 
			
		||||
 | 
			
		||||
Available options are:
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
- adaptive_height_
 | 
			
		||||
- adaptive_width_
 | 
			
		||||
- adaptive_size_
 | 
			
		||||
 | 
			
		||||
.. adaptive_height:
 | 
			
		||||
adaptive_height
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    adaptive_height: True
 | 
			
		||||
 | 
			
		||||
Equivalent
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    size_hint_y: None
 | 
			
		||||
    height: self.minimum_height
 | 
			
		||||
 | 
			
		||||
.. adaptive_width:
 | 
			
		||||
adaptive_width
 | 
			
		||||
MDAnchorLayout
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    adaptive_width: True
 | 
			
		||||
 | 
			
		||||
Equivalent
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    size_hint_x: None
 | 
			
		||||
    height: self.minimum_width
 | 
			
		||||
 | 
			
		||||
.. adaptive_size:
 | 
			
		||||
adaptive_size
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    adaptive_size: True
 | 
			
		||||
 | 
			
		||||
Equivalent
 | 
			
		||||
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    size_hint: None, None
 | 
			
		||||
    size: self.minimum_size
 | 
			
		||||
    MDAnchorLayout:
 | 
			
		||||
        md_bg_color: app.theme_cls.primary_color
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = ("MDAnchorLayout",)
 | 
			
		||||
@ -86,7 +34,11 @@ __all__ = ("MDAnchorLayout",)
 | 
			
		||||
from kivy.uix.anchorlayout import AnchorLayout
 | 
			
		||||
 | 
			
		||||
from kivymd.uix import MDAdaptiveWidget
 | 
			
		||||
from kivymd.uix.behaviors import DeclarativeBehavior
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDAnchorLayout(AnchorLayout, MDAdaptiveWidget):
 | 
			
		||||
    pass
 | 
			
		||||
class MDAnchorLayout(DeclarativeBehavior, AnchorLayout, MDAdaptiveWidget):
 | 
			
		||||
    """
 | 
			
		||||
    Anchor layout class. For more information, see in the
 | 
			
		||||
    :class:`~kivy.uix.anchorlayout.AnchorLayout` class documentation.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -35,8 +35,8 @@
 | 
			
		||||
            if not root.front_layer_color \
 | 
			
		||||
            else root.front_layer_color
 | 
			
		||||
        radius:
 | 
			
		||||
            [root.radius_left, root.radius_left,
 | 
			
		||||
            root.radius_right, root.radius_right]
 | 
			
		||||
            [root.radius_left, root.radius_right,
 | 
			
		||||
            0, 0]
 | 
			
		||||
 | 
			
		||||
        OneLineListItem:
 | 
			
		||||
            id: header_button
 | 
			
		||||
 | 
			
		||||
@ -31,84 +31,147 @@ Usage
 | 
			
		||||
Example
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
.. tabs::
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    .. tab:: Declarative KV styles
 | 
			
		||||
 | 
			
		||||
    from kivymd.uix.screen import MDScreen
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
    # Your layouts.
 | 
			
		||||
    Builder.load_string(
 | 
			
		||||
        '''
 | 
			
		||||
    #:import Window kivy.core.window.Window
 | 
			
		||||
    #:import IconLeftWidget kivymd.uix.list.IconLeftWidget
 | 
			
		||||
            from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
            from kivymd.uix.screen import MDScreen
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
            # Your layouts.
 | 
			
		||||
            Builder.load_string(
 | 
			
		||||
                '''
 | 
			
		||||
            #:import os os
 | 
			
		||||
            #:import Window kivy.core.window.Window
 | 
			
		||||
            #:import IconLeftWidget kivymd.uix.list.IconLeftWidget
 | 
			
		||||
            #:import images_path kivymd.images_path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <ItemBackdropFrontLayer@TwoLineAvatarListItem>
 | 
			
		||||
        icon: "android"
 | 
			
		||||
            <ItemBackdropFrontLayer@TwoLineAvatarListItem>
 | 
			
		||||
                icon: "android"
 | 
			
		||||
 | 
			
		||||
        IconLeftWidget:
 | 
			
		||||
            icon: root.icon
 | 
			
		||||
                IconLeftWidget:
 | 
			
		||||
                    icon: root.icon
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <MyBackdropFrontLayer@ItemBackdropFrontLayer>
 | 
			
		||||
        backdrop: None
 | 
			
		||||
        text: "Lower the front layer"
 | 
			
		||||
        secondary_text: " by 50 %"
 | 
			
		||||
        icon: "transfer-down"
 | 
			
		||||
        on_press: root.backdrop.open(-Window.height / 2)
 | 
			
		||||
        pos_hint: {"top": 1}
 | 
			
		||||
        _no_ripple_effect: True
 | 
			
		||||
            <MyBackdropFrontLayer@ItemBackdropFrontLayer>
 | 
			
		||||
                backdrop: None
 | 
			
		||||
                text: "Lower the front layer"
 | 
			
		||||
                secondary_text: " by 50 %"
 | 
			
		||||
                icon: "transfer-down"
 | 
			
		||||
                on_press: root.backdrop.open(-Window.height / 2)
 | 
			
		||||
                pos_hint: {"top": 1}
 | 
			
		||||
                _no_ripple_effect: True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <MyBackdropBackLayer@Image>
 | 
			
		||||
        size_hint: .8, .8
 | 
			
		||||
        source: "data/logo/kivy-icon-512.png"
 | 
			
		||||
        pos_hint: {"center_x": .5, "center_y": .6}
 | 
			
		||||
    '''
 | 
			
		||||
    )
 | 
			
		||||
            <MyBackdropBackLayer@Image>
 | 
			
		||||
                size_hint: .8, .8
 | 
			
		||||
                source: os.path.join(images_path, "logo", "kivymd-icon-512.png")
 | 
			
		||||
                pos_hint: {"center_x": .5, "center_y": .6}
 | 
			
		||||
            '''
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    # Usage example of MDBackdrop.
 | 
			
		||||
    Builder.load_string(
 | 
			
		||||
        '''
 | 
			
		||||
    <ExampleBackdrop>
 | 
			
		||||
            # Usage example of MDBackdrop.
 | 
			
		||||
            Builder.load_string(
 | 
			
		||||
                '''
 | 
			
		||||
            <ExampleBackdrop>
 | 
			
		||||
 | 
			
		||||
        MDBackdrop:
 | 
			
		||||
            id: backdrop
 | 
			
		||||
            left_action_items: [['menu', lambda x: self.open()]]
 | 
			
		||||
            title: "Example Backdrop"
 | 
			
		||||
            radius_left: "25dp"
 | 
			
		||||
            radius_right: "0dp"
 | 
			
		||||
            header_text: "Menu:"
 | 
			
		||||
                MDBackdrop:
 | 
			
		||||
                    id: backdrop
 | 
			
		||||
                    left_action_items: [['menu', lambda x: self.open()]]
 | 
			
		||||
                    title: "Example Backdrop"
 | 
			
		||||
                    radius_left: "25dp"
 | 
			
		||||
                    radius_right: "0dp"
 | 
			
		||||
                    header_text: "Menu:"
 | 
			
		||||
 | 
			
		||||
            MDBackdropBackLayer:
 | 
			
		||||
                MyBackdropBackLayer:
 | 
			
		||||
                    id: backlayer
 | 
			
		||||
                    MDBackdropBackLayer:
 | 
			
		||||
                        MyBackdropBackLayer:
 | 
			
		||||
                            id: backlayer
 | 
			
		||||
 | 
			
		||||
            MDBackdropFrontLayer:
 | 
			
		||||
                MyBackdropFrontLayer:
 | 
			
		||||
                    backdrop: backdrop
 | 
			
		||||
    '''
 | 
			
		||||
    )
 | 
			
		||||
                    MDBackdropFrontLayer:
 | 
			
		||||
                        MyBackdropFrontLayer:
 | 
			
		||||
                            backdrop: backdrop
 | 
			
		||||
            '''
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class ExampleBackdrop(MDScreen):
 | 
			
		||||
        pass
 | 
			
		||||
            class ExampleBackdrop(MDScreen):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class TestBackdrop(MDApp):
 | 
			
		||||
        def __init__(self, **kwargs):
 | 
			
		||||
            super().__init__(**kwargs)
 | 
			
		||||
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return ExampleBackdrop()
 | 
			
		||||
            class Example(MDApp):
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                    return ExampleBackdrop()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    TestBackdrop().run()
 | 
			
		||||
            Example().run()
 | 
			
		||||
 | 
			
		||||
    .. tab:: Declarative python styles
 | 
			
		||||
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
            import os
 | 
			
		||||
 | 
			
		||||
            from kivy.core.window import Window
 | 
			
		||||
            from kivy.uix.image import Image
 | 
			
		||||
 | 
			
		||||
            from kivymd import images_path
 | 
			
		||||
            from kivymd.uix.backdrop import MDBackdrop
 | 
			
		||||
            from kivymd.uix.backdrop.backdrop import (
 | 
			
		||||
                MDBackdropBackLayer, MDBackdropFrontLayer
 | 
			
		||||
            )
 | 
			
		||||
            from kivymd.uix.list import TwoLineAvatarListItem, IconLeftWidget
 | 
			
		||||
            from kivymd.uix.screen import MDScreen
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            class Example(MDApp):
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                    return (
 | 
			
		||||
                        MDScreen(
 | 
			
		||||
                            MDBackdrop(
 | 
			
		||||
                                MDBackdropBackLayer(
 | 
			
		||||
                                    Image(
 | 
			
		||||
                                        size_hint=(0.8, 0.8),
 | 
			
		||||
                                        source=os.path.join(images_path, "logo", "kivymd-icon-512.png"),
 | 
			
		||||
                                        pos_hint={"center_x": 0.5, "center_y": 0.6},
 | 
			
		||||
                                    )
 | 
			
		||||
                                ),
 | 
			
		||||
                                MDBackdropFrontLayer(
 | 
			
		||||
                                    TwoLineAvatarListItem(
 | 
			
		||||
                                        IconLeftWidget(icon="transfer-down"),
 | 
			
		||||
                                        text="Lower the front layer",
 | 
			
		||||
                                        secondary_text=" by 50 %",
 | 
			
		||||
                                        on_press=self.backdrop_open_by_50_percent,
 | 
			
		||||
                                        pos_hint={"top": 1},
 | 
			
		||||
                                        _no_ripple_effect=True,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                ),
 | 
			
		||||
                                id="backdrop",
 | 
			
		||||
                                title="Example Backdrop",
 | 
			
		||||
                                radius_left="25dp",
 | 
			
		||||
                                radius_right="0dp",
 | 
			
		||||
                                header_text="Menu:",
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
                def backdrop_open_by_50_percent(self, *args):
 | 
			
		||||
                    self.root.ids.backdrop.open(-Window.height / 2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            Example().run()
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop.gif
 | 
			
		||||
    :width: 280 px
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. Note:: `See full example <https://github.com/kivymd/KivyMD/wiki/Components-Backdrop>`_
 | 
			
		||||
@ -139,7 +202,7 @@ from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.theming import ThemableBehavior
 | 
			
		||||
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
 | 
			
		||||
from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
from kivymd.uix.card import MDCard
 | 
			
		||||
from kivymd.uix.floatlayout import MDFloatLayout
 | 
			
		||||
from kivymd.uix.toolbar.toolbar import ActionTopAppBarButton, MDTopAppBar
 | 
			
		||||
@ -151,7 +214,7 @@ with open(
 | 
			
		||||
    Builder.load_string(kv_file.read())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
class MDBackdrop(MDFloatLayout, ThemableBehavior):
 | 
			
		||||
    """
 | 
			
		||||
    :Events:
 | 
			
		||||
        :attr:`on_open`
 | 
			
		||||
@ -167,6 +230,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-anchor-title.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`anchor_title` is an :class:`~kivy.properties.OptionProperty`
 | 
			
		||||
    and defaults to `'left'`.
 | 
			
		||||
    """
 | 
			
		||||
@ -175,6 +241,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Padding for contents of the front layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-padding.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`padding` is an :class:`~kivy.properties.ListProperty`
 | 
			
		||||
    and defaults to `[0, 0, 0, 0]`.
 | 
			
		||||
    """
 | 
			
		||||
@ -210,6 +279,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Background color of back layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-back-layer-color.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`back_layer_color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
@ -218,6 +290,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Background color of front layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-front-layer-color.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`front_layer_color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
@ -227,6 +302,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    The value of the rounding radius of the upper left corner
 | 
			
		||||
    of the front layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-radius-left.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`radius_left` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `16dp`.
 | 
			
		||||
    """
 | 
			
		||||
@ -244,6 +322,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Whether to use a header above the contents of the front layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-header.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`header` is an :class:`~kivy.properties.BooleanProperty`
 | 
			
		||||
    and defaults to `True`.
 | 
			
		||||
    """
 | 
			
		||||
@ -252,6 +333,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Text of header.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-header-text.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`header_text` is an :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    and defaults to `'Header'`.
 | 
			
		||||
    """
 | 
			
		||||
@ -261,6 +345,9 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    The name of the icon that will be installed on the toolbar
 | 
			
		||||
    on the left when opening the front layer.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/backdrop-close-icon.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`close_icon` is an :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    and defaults to `'close'`.
 | 
			
		||||
    """
 | 
			
		||||
@ -310,8 +397,8 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
    _open_icon = ""
 | 
			
		||||
    _front_layer_open = False
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.register_event_type("on_open")
 | 
			
		||||
        self.register_event_type("on_close")
 | 
			
		||||
        Clock.schedule_once(
 | 
			
		||||
@ -332,8 +419,11 @@ class MDBackdrop(ThemableBehavior, MDFloatLayout):
 | 
			
		||||
        self._open_icon = self.left_action_items[0][0]
 | 
			
		||||
 | 
			
		||||
    def on_header(self, instance_backdrop, value: bool) -> None:
 | 
			
		||||
        if not value:
 | 
			
		||||
            self.ids._front_layer.remove_widget(self.ids.header_button)
 | 
			
		||||
        def on_header(*args):
 | 
			
		||||
            if not value:
 | 
			
		||||
                self.ids._front_layer.remove_widget(self.ids.header_button)
 | 
			
		||||
 | 
			
		||||
        Clock.schedule_once(on_header)
 | 
			
		||||
 | 
			
		||||
    def open(self, open_up_to: int = 0) -> None:
 | 
			
		||||
        """
 | 
			
		||||
@ -425,11 +515,11 @@ class MDBackdropToolbar(MDTopAppBar):
 | 
			
		||||
    """Implements a toolbar for back content."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBackdropFrontLayer(BoxLayout):
 | 
			
		||||
class MDBackdropFrontLayer(MDBoxLayout):
 | 
			
		||||
    """Container for front content."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBackdropBackLayer(BoxLayout):
 | 
			
		||||
class MDBackdropBackLayer(MDBoxLayout):
 | 
			
		||||
    """Container for back content."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -437,5 +527,5 @@ class _BackLayer(BoxLayout):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _FrontLayer(MDCard, FakeRectangularElevationBehavior):
 | 
			
		||||
class _FrontLayer(MDCard):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ Usage
 | 
			
		||||
        MDTopAppBar:
 | 
			
		||||
            id: toolbar
 | 
			
		||||
            title: "Example Banners"
 | 
			
		||||
            elevation: 10
 | 
			
		||||
            elevation: 4
 | 
			
		||||
            pos_hint: {'top': 1}
 | 
			
		||||
 | 
			
		||||
        MDBoxLayout:
 | 
			
		||||
@ -157,7 +157,6 @@ from kivy.properties import (
 | 
			
		||||
from kivy.uix.widget import Widget
 | 
			
		||||
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
 | 
			
		||||
from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
from kivymd.uix.button import MDFlatButton
 | 
			
		||||
from kivymd.uix.card import MDCard
 | 
			
		||||
@ -177,7 +176,7 @@ with open(
 | 
			
		||||
    Builder.load_string(kv_file.read())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBanner(MDCard, FakeRectangularElevationBehavior):
 | 
			
		||||
class MDBanner(MDCard):
 | 
			
		||||
    vertical_pad = NumericProperty(dp(68))
 | 
			
		||||
    """
 | 
			
		||||
    Indent the banner at the top of the screen.
 | 
			
		||||
 | 
			
		||||
@ -5,22 +5,26 @@ Behaviors
 | 
			
		||||
Modules and classes implementing various behaviors for buttons etc.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# flake8: NOQA
 | 
			
		||||
from .hover_behavior import HoverBehavior  # isort:skip
 | 
			
		||||
from .backgroundcolor_behavior import (
 | 
			
		||||
    BackgroundColorBehavior,
 | 
			
		||||
    SpecificBackgroundColorBehavior,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# flake8: NOQA
 | 
			
		||||
from .declarative_behavior import DeclarativeBehavior
 | 
			
		||||
from .elevation import (
 | 
			
		||||
    CircularElevationBehavior,
 | 
			
		||||
    CommonElevationBehavior,
 | 
			
		||||
    FakeCircularElevationBehavior,
 | 
			
		||||
    FakeRectangularElevationBehavior,
 | 
			
		||||
    ObservableShadow,
 | 
			
		||||
    RectangularElevationBehavior,
 | 
			
		||||
    RoundedRectangularElevationBehavior,
 | 
			
		||||
)
 | 
			
		||||
from .focus_behavior import FocusBehavior
 | 
			
		||||
from .magic_behavior import MagicBehavior
 | 
			
		||||
from .ripple_behavior import CircularRippleBehavior, RectangularRippleBehavior
 | 
			
		||||
from .rotate_behavior import RotateBehavior
 | 
			
		||||
from .scale_behavior import ScaleBehavior
 | 
			
		||||
from .stencil_behavior import StencilBehavior
 | 
			
		||||
from .touch_behavior import TouchBehavior
 | 
			
		||||
 | 
			
		||||
from .hover_behavior import HoverBehavior  # isort:skip
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,9 @@ Behaviors/Background Color
 | 
			
		||||
 | 
			
		||||
__all__ = ("BackgroundColorBehavior", "SpecificBackgroundColorBehavior")
 | 
			
		||||
 | 
			
		||||
from typing import List
 | 
			
		||||
from typing import List, Union
 | 
			
		||||
 | 
			
		||||
from kivy.animation import Animation
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.properties import (
 | 
			
		||||
    ColorProperty,
 | 
			
		||||
@ -24,8 +25,6 @@ from kivy.utils import get_color_from_hex
 | 
			
		||||
from kivymd.color_definitions import hue, palette, text_colors
 | 
			
		||||
from kivymd.theming import ThemeManager
 | 
			
		||||
 | 
			
		||||
from .elevation import CommonElevationBehavior
 | 
			
		||||
 | 
			
		||||
Builder.load_string(
 | 
			
		||||
    """
 | 
			
		||||
#:import RelativeLayout kivy.uix.relativelayout.RelativeLayout
 | 
			
		||||
@ -38,7 +37,7 @@ Builder.load_string(
 | 
			
		||||
            angle: self.angle
 | 
			
		||||
            origin: self._background_origin
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba: self.md_bg_color
 | 
			
		||||
            rgba: self._md_bg_color
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            group: "Background_instruction"
 | 
			
		||||
            size: self.size
 | 
			
		||||
@ -67,7 +66,7 @@ Builder.load_string(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BackgroundColorBehavior(CommonElevationBehavior):
 | 
			
		||||
class BackgroundColorBehavior:
 | 
			
		||||
    background = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Background image path.
 | 
			
		||||
@ -153,15 +152,26 @@ class BackgroundColorBehavior(CommonElevationBehavior):
 | 
			
		||||
 | 
			
		||||
    _background_x = NumericProperty(0)
 | 
			
		||||
    _background_y = NumericProperty(0)
 | 
			
		||||
    _background_origin = ReferenceListProperty(
 | 
			
		||||
        _background_x,
 | 
			
		||||
        _background_y,
 | 
			
		||||
    )
 | 
			
		||||
    _background_origin = ReferenceListProperty(_background_x, _background_y)
 | 
			
		||||
    _md_bg_color = ColorProperty([0, 0, 0, 0])
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwarg):
 | 
			
		||||
        super().__init__(**kwarg)
 | 
			
		||||
        self.bind(pos=self.update_background_origin)
 | 
			
		||||
 | 
			
		||||
    def on_md_bg_color(self, instance_md_widget, color: Union[list, str]):
 | 
			
		||||
        if (
 | 
			
		||||
            hasattr(self, "theme_cls")
 | 
			
		||||
            and self.theme_cls.theme_style_switch_animation
 | 
			
		||||
        ):
 | 
			
		||||
            Animation(
 | 
			
		||||
                _md_bg_color=color,
 | 
			
		||||
                d=self.theme_cls.theme_style_switch_animation_duration,
 | 
			
		||||
                t="linear",
 | 
			
		||||
            ).start(self)
 | 
			
		||||
        else:
 | 
			
		||||
            self._md_bg_color = color
 | 
			
		||||
 | 
			
		||||
    def update_background_origin(
 | 
			
		||||
        self, instance_md_widget, pos: List[float]
 | 
			
		||||
    ) -> None:
 | 
			
		||||
@ -206,12 +216,14 @@ class SpecificBackgroundColorBehavior(BackgroundColorBehavior):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
        if hasattr(self, "theme_cls"):
 | 
			
		||||
            self.theme_cls.bind(
 | 
			
		||||
                primary_palette=self._update_specific_text_color
 | 
			
		||||
                primary_palette=self._update_specific_text_color,
 | 
			
		||||
                accent_palette=self._update_specific_text_color,
 | 
			
		||||
                theme_style=self._update_specific_text_color,
 | 
			
		||||
            )
 | 
			
		||||
            self.theme_cls.bind(accent_palette=self._update_specific_text_color)
 | 
			
		||||
            self.theme_cls.bind(theme_style=self._update_specific_text_color)
 | 
			
		||||
        self.bind(background_hue=self._update_specific_text_color)
 | 
			
		||||
        self.bind(background_palette=self._update_specific_text_color)
 | 
			
		||||
        self.bind(
 | 
			
		||||
            background_hue=self._update_specific_text_color,
 | 
			
		||||
            background_palette=self._update_specific_text_color,
 | 
			
		||||
        )
 | 
			
		||||
        self._update_specific_text_color(None, None)
 | 
			
		||||
 | 
			
		||||
    def _update_specific_text_color(
 | 
			
		||||
@ -234,5 +246,17 @@ class SpecificBackgroundColorBehavior(BackgroundColorBehavior):
 | 
			
		||||
            secondary_color[3] = 0.54
 | 
			
		||||
        else:
 | 
			
		||||
            secondary_color[3] = 0.7
 | 
			
		||||
        self.specific_text_color = color
 | 
			
		||||
        self.specific_secondary_text_color = secondary_color
 | 
			
		||||
 | 
			
		||||
        if (
 | 
			
		||||
            hasattr(self, "theme_cls")
 | 
			
		||||
            and self.theme_cls.theme_style_switch_animation
 | 
			
		||||
        ):
 | 
			
		||||
            Animation(
 | 
			
		||||
                specific_text_color=color,
 | 
			
		||||
                specific_secondary_text_color=secondary_color,
 | 
			
		||||
                d=self.theme_cls.theme_style_switch_animation_duration,
 | 
			
		||||
                t="linear",
 | 
			
		||||
            ).start(self)
 | 
			
		||||
        else:
 | 
			
		||||
            self.specific_text_color = color
 | 
			
		||||
            self.specific_secondary_text_color = secondary_color
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										317
									
								
								sbapp/kivymd/uix/behaviors/declarative_behavior.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,317 @@
 | 
			
		||||
"""
 | 
			
		||||
Behaviors/Declarative
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
.. raw:: html
 | 
			
		||||
 | 
			
		||||
    <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; height: auto;">
 | 
			
		||||
        <iframe
 | 
			
		||||
            src="https://www.youtube.com/embed/_kiaJacLz8o"
 | 
			
		||||
            frameborder="0"
 | 
			
		||||
            allowfullscreen
 | 
			
		||||
            style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
 | 
			
		||||
        </iframe>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
As you already know, the Kivy framework provides the best/simplest/modern
 | 
			
		||||
UI creation tool that allows you to separate the logic of your application
 | 
			
		||||
from the description of the properties of widgets/GUI components.
 | 
			
		||||
This tool is named `KV Language <https://kivy.org/doc/stable/guide/lang.html>`_.
 | 
			
		||||
 | 
			
		||||
But in addition to creating a user interface using the KV Language Kivy allows
 | 
			
		||||
you to create user interface elements directly in the Python code.
 | 
			
		||||
And if you've ever created a user interface in Python code, you know how ugly
 | 
			
		||||
it looks. Even in the simplest user interface design, which was created using
 | 
			
		||||
Python code it is impossible to trace the widget tree, because in Python code
 | 
			
		||||
you build the user interface in an imperative style.
 | 
			
		||||
 | 
			
		||||
Imperative style
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.bottomnavigation import MDBottomNavigation, MDBottomNavigationItem
 | 
			
		||||
    from kivymd.uix.label import MDLabel
 | 
			
		||||
    from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Example(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            screen = MDScreen()
 | 
			
		||||
            bottom_navigation = MDBottomNavigation(
 | 
			
		||||
                panel_color="#eeeaea",
 | 
			
		||||
                selected_color_background="#97ecf8",
 | 
			
		||||
                text_color_active="white",
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            data = {
 | 
			
		||||
                "screen 1": {"text": "Mail", "icon": "gmail"},
 | 
			
		||||
                "screen 2": {"text": "Discord", "icon": "discord"},
 | 
			
		||||
                "screen 3": {"text": "LinkedIN", "icon": "linkedin"},
 | 
			
		||||
            }
 | 
			
		||||
            for key in data.keys():
 | 
			
		||||
                text = data[key]["text"]
 | 
			
		||||
                navigation_item = MDBottomNavigationItem(
 | 
			
		||||
                    name=key, text=text, icon=data[key]["icon"]
 | 
			
		||||
                )
 | 
			
		||||
                navigation_item.add_widget(MDLabel(text=text, halign="center"))
 | 
			
		||||
                bottom_navigation.add_widget(navigation_item)
 | 
			
		||||
 | 
			
		||||
            screen.add_widget(bottom_navigation)
 | 
			
		||||
            return screen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Example().run()
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/bottom-navigation-styles-programming.png
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
Take a look at the above code example. This is a very simple UI. But looking
 | 
			
		||||
at this code, you will not be able to figure the widget tree and understand
 | 
			
		||||
which UI this code implements. This is named imperative programming style,
 | 
			
		||||
which is used in Kivy.
 | 
			
		||||
 | 
			
		||||
Now let's see how the same code is implemented using the KV language,
 | 
			
		||||
which uses a declarative style of describing widget properties.
 | 
			
		||||
 | 
			
		||||
Declarative style with KV language
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(
 | 
			
		||||
                '''
 | 
			
		||||
    MDScreen:
 | 
			
		||||
 | 
			
		||||
        MDBottomNavigation:
 | 
			
		||||
            panel_color: "#eeeaea"
 | 
			
		||||
            selected_color_background: "#97ecf8"
 | 
			
		||||
            text_color_active: "white"
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: "screen 1"
 | 
			
		||||
                text: "Mail"
 | 
			
		||||
                icon: "gmail"
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: "Mail"
 | 
			
		||||
                    halign: "center"
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: "screen 2"
 | 
			
		||||
                text: "Discord"
 | 
			
		||||
                icon: "discord"
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: "Discord"
 | 
			
		||||
                    halign: "center"
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: "screen 3"
 | 
			
		||||
                text: "LinkedIN"
 | 
			
		||||
                icon: "linkedin"
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: "LinkedIN"
 | 
			
		||||
                    halign: "center"
 | 
			
		||||
    '''
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/bottom-navigation-styles-programming.png
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
Looking at this code, we can now clearly see the widget tree and their properties.
 | 
			
		||||
We can quickly navigate through the components of the screen and quickly
 | 
			
		||||
change/add new properties/widgets. This is named declarative UI creation style.
 | 
			
		||||
 | 
			
		||||
But now the KivyMD library allows you to write Python code in a declarative style.
 | 
			
		||||
Just as it is implemented in Flutter/Jetpack Compose/SwiftUI.
 | 
			
		||||
 | 
			
		||||
Declarative style with Python code
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.bottomnavigation import MDBottomNavigation, MDBottomNavigationItem
 | 
			
		||||
    from kivymd.uix.label import MDLabel
 | 
			
		||||
    from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Example(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return (
 | 
			
		||||
                MDScreen(
 | 
			
		||||
                    MDBottomNavigation(
 | 
			
		||||
                        MDBottomNavigationItem(
 | 
			
		||||
                            MDLabel(
 | 
			
		||||
                                text="Mail",
 | 
			
		||||
                                halign="center",
 | 
			
		||||
                            ),
 | 
			
		||||
                            name="screen 1",
 | 
			
		||||
                            text="Mail",
 | 
			
		||||
                            icon="gmail",
 | 
			
		||||
                        ),
 | 
			
		||||
                        MDBottomNavigationItem(
 | 
			
		||||
                            MDLabel(
 | 
			
		||||
                                text="Discord",
 | 
			
		||||
                                halign="center",
 | 
			
		||||
                            ),
 | 
			
		||||
                            name="screen 2",
 | 
			
		||||
                            text="Discord",
 | 
			
		||||
                            icon="discord",
 | 
			
		||||
                        ),
 | 
			
		||||
                        MDBottomNavigationItem(
 | 
			
		||||
                            MDLabel(
 | 
			
		||||
                                text="LinkedIN",
 | 
			
		||||
                                halign="center",
 | 
			
		||||
                            ),
 | 
			
		||||
                            name="screen 3",
 | 
			
		||||
                            text="LinkedIN",
 | 
			
		||||
                            icon="linkedin",
 | 
			
		||||
                        ),
 | 
			
		||||
                        panel_color="#eeeaea",
 | 
			
		||||
                        selected_color_background="#97ecf8",
 | 
			
		||||
                        text_color_active="white",
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Example().run()
 | 
			
		||||
 | 
			
		||||
.. note:: The KivyMD library does not support creating Kivy widgets in Python
 | 
			
		||||
    code in a declarative style.
 | 
			
		||||
 | 
			
		||||
But you can still use the declarative style of creating Kivy widgets in Python code.
 | 
			
		||||
To do this, you need to create a new class that will be inherited from the Kivy
 | 
			
		||||
widget and the :class:`~DeclarativeBehavior` class:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
    from kivy.uix.button import Button
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.behaviors import DeclarativeBehavior
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class DeclarativeStyleBoxLayout(DeclarativeBehavior, BoxLayout):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Example(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return (
 | 
			
		||||
                DeclarativeStyleBoxLayout(
 | 
			
		||||
                    Button(),
 | 
			
		||||
                    Button(),
 | 
			
		||||
                    orientation="vertical",
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Example().run()
 | 
			
		||||
 | 
			
		||||
Get objects by identifiers
 | 
			
		||||
--------------------------
 | 
			
		||||
 | 
			
		||||
In the declarative style in Python code, the ids parameter of the specified
 | 
			
		||||
widget will return only the id of the child widget/container, ignoring other ids.
 | 
			
		||||
Therefore, to get objects by identifiers in declarative style in Python code,
 | 
			
		||||
you must specify all the container ids in which the widget is nested until you
 | 
			
		||||
get to the desired id:
 | 
			
		||||
 | 
			
		||||
.. code-block::
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
    from kivymd.uix.button import MDRaisedButton
 | 
			
		||||
    from kivymd.uix.floatlayout import MDFloatLayout
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Example(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return (
 | 
			
		||||
                MDBoxLayout(
 | 
			
		||||
                    MDFloatLayout(
 | 
			
		||||
                        MDRaisedButton(
 | 
			
		||||
                            id="button_1",
 | 
			
		||||
                            text="Button 1",
 | 
			
		||||
                            pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                        ),
 | 
			
		||||
                        id="box_container_1",
 | 
			
		||||
                    ),
 | 
			
		||||
                    MDBoxLayout(
 | 
			
		||||
                        MDFloatLayout(
 | 
			
		||||
                            MDRaisedButton(
 | 
			
		||||
                                id="button_2",
 | 
			
		||||
                                text="Button 2",
 | 
			
		||||
                                pos_hint={"center_x": 0.5, "center_y": 0.5},
 | 
			
		||||
                            ),
 | 
			
		||||
                            id="float_container",
 | 
			
		||||
                        ),
 | 
			
		||||
                        id="box_container_2",
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        def on_start(self):
 | 
			
		||||
            # {
 | 
			
		||||
            #     'box_container_1': <kivymd.uix.floatlayout.MDFloatLayout>,
 | 
			
		||||
            #     'box_container_2': <kivymd.uix.boxlayout.MDBoxLayout object>
 | 
			
		||||
            # }
 | 
			
		||||
            print(self.root.ids)
 | 
			
		||||
 | 
			
		||||
            # <kivymd.uix.button.button.MDRaisedButton>
 | 
			
		||||
            print(self.root.ids.box_container_2.ids.float_container.ids.button_2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Example().run()
 | 
			
		||||
 | 
			
		||||
Yes, this is not a very good solution, but I think it will be fixed soon.
 | 
			
		||||
 | 
			
		||||
.. warning:: Declarative programming style in Python code in the KivyMD library
 | 
			
		||||
    is an experimental feature. Therefore, if you receive errors, do not hesitate
 | 
			
		||||
    to create new issue in the KivyMD repository.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from kivy.properties import StringProperty
 | 
			
		||||
from kivy.uix.widget import Widget
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DeclarativeBehavior:
 | 
			
		||||
    """
 | 
			
		||||
    Implements the creation and addition of child widgets as declarative
 | 
			
		||||
    programming style.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    id = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Widget ID.
 | 
			
		||||
 | 
			
		||||
    :attr:`id` is an :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
 | 
			
		||||
        for child in args:
 | 
			
		||||
            if issubclass(child.__class__, Widget):
 | 
			
		||||
                self.add_widget(child)
 | 
			
		||||
                if hasattr(child, "id") and child.id:
 | 
			
		||||
                    self.ids[child.id] = child
 | 
			
		||||
@ -100,23 +100,35 @@ class FocusBehavior(HoverBehavior, ButtonBehavior):
 | 
			
		||||
    def on_enter(self):
 | 
			
		||||
        """Called when mouse enter the bbox of the widget."""
 | 
			
		||||
 | 
			
		||||
        if hasattr(self, "md_bg_color") and self.focus_behavior:
 | 
			
		||||
        if (
 | 
			
		||||
            hasattr(self, "md_bg_color") or hasattr(self, "bg_color")
 | 
			
		||||
        ) and self.focus_behavior:
 | 
			
		||||
            if hasattr(self, "theme_cls") and not self.focus_color:
 | 
			
		||||
                self.md_bg_color = self.theme_cls.bg_normal
 | 
			
		||||
                color = self.theme_cls.bg_normal
 | 
			
		||||
            else:
 | 
			
		||||
                if not self.focus_color:
 | 
			
		||||
                    self.md_bg_color = App.get_running_app().theme_cls.bg_normal
 | 
			
		||||
                    color = App.get_running_app().theme_cls.bg_normal
 | 
			
		||||
                else:
 | 
			
		||||
                    self.md_bg_color = self.focus_color
 | 
			
		||||
                    color = self.focus_color
 | 
			
		||||
            self._set_bg_color(color)
 | 
			
		||||
 | 
			
		||||
    def on_leave(self):
 | 
			
		||||
        """Called when the mouse exit the widget."""
 | 
			
		||||
 | 
			
		||||
        if hasattr(self, "md_bg_color") and self.focus_behavior:
 | 
			
		||||
        if (
 | 
			
		||||
            hasattr(self, "md_bg_color") or hasattr(self, "bg_color")
 | 
			
		||||
        ) and self.focus_behavior:
 | 
			
		||||
            if hasattr(self, "theme_cls") and not self.unfocus_color:
 | 
			
		||||
                self.md_bg_color = self.theme_cls.bg_light
 | 
			
		||||
                color = self.theme_cls.bg_light
 | 
			
		||||
            else:
 | 
			
		||||
                if not self.unfocus_color:
 | 
			
		||||
                    self.md_bg_color = App.get_running_app().theme_cls.bg_light
 | 
			
		||||
                    color = App.get_running_app().theme_cls.bg_light
 | 
			
		||||
                else:
 | 
			
		||||
                    self.md_bg_color = self.unfocus_color
 | 
			
		||||
                    color = self.unfocus_color
 | 
			
		||||
            self._set_bg_color(color)
 | 
			
		||||
 | 
			
		||||
    def _set_bg_color(self, color):
 | 
			
		||||
        if hasattr(self, "md_bg_color"):
 | 
			
		||||
            self.md_bg_color = color
 | 
			
		||||
        elif hasattr(self, "bg_color"):
 | 
			
		||||
            self.bg_color = color
 | 
			
		||||
 | 
			
		||||
@ -111,7 +111,7 @@ from kivy.properties import (
 | 
			
		||||
from kivy.uix.behaviors import ToggleButtonBehavior
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CommonRipple(object):
 | 
			
		||||
class CommonRipple:
 | 
			
		||||
    """Base class for ripple effect."""
 | 
			
		||||
 | 
			
		||||
    ripple_rad_default = NumericProperty(1)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										133
									
								
								sbapp/kivymd/uix/behaviors/rotate_behavior.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,133 @@
 | 
			
		||||
"""
 | 
			
		||||
Behaviors/Rotate
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
Base class for controlling the rotate of the widget.
 | 
			
		||||
 | 
			
		||||
.. note:: See `kivy.graphics.Rotate
 | 
			
		||||
    <https://kivy.org/doc/stable/api-kivy.graphics.html#kivy.graphics.Rotate>`_
 | 
			
		||||
    for more information.
 | 
			
		||||
 | 
			
		||||
Kivy
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.animation import Animation
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    from kivy.app import App
 | 
			
		||||
    from kivy.properties import NumericProperty
 | 
			
		||||
    from kivy.uix.button import Button
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    Screen:
 | 
			
		||||
 | 
			
		||||
        RotateButton:
 | 
			
		||||
            size_hint: .5, .5
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            on_release: app.change_rotate(self)
 | 
			
		||||
 | 
			
		||||
            canvas.before:
 | 
			
		||||
                PushMatrix
 | 
			
		||||
                Rotate:
 | 
			
		||||
                    angle: self.rotate_value_angle
 | 
			
		||||
                    axis: 0, 0, 1
 | 
			
		||||
                    origin: self.center
 | 
			
		||||
            canvas.after:
 | 
			
		||||
                PopMatrix
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class RotateButton(Button):
 | 
			
		||||
        rotate_value_angle = NumericProperty(0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(App):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
        def change_rotate(self, instance_button: Button) -> None:
 | 
			
		||||
            Animation(rotate_value_angle=45, d=0.3).start(instance_button)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
 | 
			
		||||
KivyMD
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.animation import Animation
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    from kivy.uix.behaviors import ButtonBehavior
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.behaviors import RotateBehavior
 | 
			
		||||
    from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    MDScreen:
 | 
			
		||||
 | 
			
		||||
        RotateBox:
 | 
			
		||||
            size_hint: .5, .5
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            on_release: app.change_rotate(self)
 | 
			
		||||
            md_bg_color: "red"
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class RotateBox(ButtonBehavior, RotateBehavior, MDBoxLayout):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
        def change_rotate(self, instance_button: RotateBox) -> None:
 | 
			
		||||
            Animation(rotate_value_angle=45, d=0.3).start(instance_button)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = ("RotateBehavior",)
 | 
			
		||||
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.properties import ListProperty, NumericProperty
 | 
			
		||||
 | 
			
		||||
Builder.load_string(
 | 
			
		||||
    """
 | 
			
		||||
<RotateBehavior>
 | 
			
		||||
    canvas.before:
 | 
			
		||||
        PushMatrix
 | 
			
		||||
        Rotate:
 | 
			
		||||
            angle: self.rotate_value_angle
 | 
			
		||||
            axis: tuple(self.rotate_value_axis)
 | 
			
		||||
            origin: self.center
 | 
			
		||||
    canvas.after:
 | 
			
		||||
        PopMatrix
 | 
			
		||||
"""
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RotateBehavior:
 | 
			
		||||
    """Base class for controlling the rotate of the widget."""
 | 
			
		||||
 | 
			
		||||
    rotate_value_angle = NumericProperty(0)
 | 
			
		||||
    """
 | 
			
		||||
    Property for getting/setting the angle of the rotation.
 | 
			
		||||
 | 
			
		||||
    :attr:`rotate_value_angle` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `0`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    rotate_value_axis = ListProperty((0, 0, 1))
 | 
			
		||||
    """
 | 
			
		||||
    Property for getting/setting the axis of the rotation.
 | 
			
		||||
 | 
			
		||||
    :attr:`rotate_value_axis` is an :class:`~kivy.properties.ListProperty`
 | 
			
		||||
    and defaults to `(0, 0, 1)`.
 | 
			
		||||
    """
 | 
			
		||||
							
								
								
									
										156
									
								
								sbapp/kivymd/uix/behaviors/scale_behavior.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,156 @@
 | 
			
		||||
"""
 | 
			
		||||
Behaviors/Scale
 | 
			
		||||
===============
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
Base class for controlling the scale of the widget.
 | 
			
		||||
 | 
			
		||||
.. note:: See `kivy.graphics.Rotate
 | 
			
		||||
    <https://kivy.org/doc/stable/api-kivy.graphics.html#kivy.graphics.Scale>`_
 | 
			
		||||
    for more information.
 | 
			
		||||
 | 
			
		||||
Kivy
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.animation import Animation
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    from kivy.properties import NumericProperty
 | 
			
		||||
    from kivy.uix.button import Button
 | 
			
		||||
    from kivy.app import App
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    Screen:
 | 
			
		||||
 | 
			
		||||
        ScaleButton:
 | 
			
		||||
            size_hint: .5, .5
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            on_release: app.change_scale(self)
 | 
			
		||||
 | 
			
		||||
            canvas.before:
 | 
			
		||||
                PushMatrix
 | 
			
		||||
                Scale:
 | 
			
		||||
                    x: self.scale_value_x
 | 
			
		||||
                    y: self.scale_value_y
 | 
			
		||||
                    z: self.scale_value_x
 | 
			
		||||
                    origin: self.center
 | 
			
		||||
            canvas.after:
 | 
			
		||||
                PopMatrix
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class ScaleButton(Button):
 | 
			
		||||
        scale_value_x = NumericProperty(1)
 | 
			
		||||
        scale_value_y = NumericProperty(1)
 | 
			
		||||
        scale_value_z = NumericProperty(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(App):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
        def change_scale(self, instance_button: Button) -> None:
 | 
			
		||||
            Animation(
 | 
			
		||||
                scale_value_x=0.5,
 | 
			
		||||
                scale_value_y=0.5,
 | 
			
		||||
                scale_value_z=0.5,
 | 
			
		||||
                d=0.3,
 | 
			
		||||
            ).start(instance_button)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
 | 
			
		||||
KivyMD
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.animation import Animation
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    from kivy.uix.behaviors import ButtonBehavior
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.behaviors import ScaleBehavior
 | 
			
		||||
    from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    MDScreen:
 | 
			
		||||
 | 
			
		||||
        ScaleBox:
 | 
			
		||||
            size_hint: .5, .5
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            on_release: app.change_scale(self)
 | 
			
		||||
            md_bg_color: "red"
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class ScaleBox(ButtonBehavior, ScaleBehavior, MDBoxLayout):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
        def change_scale(self, instance_button: ScaleBox) -> None:
 | 
			
		||||
            Animation(
 | 
			
		||||
                scale_value_x=0.5,
 | 
			
		||||
                scale_value_y=0.5,
 | 
			
		||||
                scale_value_z=0.5,
 | 
			
		||||
                d=0.3,
 | 
			
		||||
            ).start(instance_button)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = ("ScaleBehavior",)
 | 
			
		||||
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.properties import NumericProperty
 | 
			
		||||
 | 
			
		||||
Builder.load_string(
 | 
			
		||||
    """
 | 
			
		||||
<ScaleBehavior>
 | 
			
		||||
    canvas.before:
 | 
			
		||||
        PushMatrix
 | 
			
		||||
        Scale:
 | 
			
		||||
            x: self.scale_value_x
 | 
			
		||||
            y: self.scale_value_y
 | 
			
		||||
            z: self.scale_value_x
 | 
			
		||||
            origin: self.center
 | 
			
		||||
    canvas.after:
 | 
			
		||||
        PopMatrix
 | 
			
		||||
"""
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ScaleBehavior:
 | 
			
		||||
    """Base class for controlling the scale of the widget."""
 | 
			
		||||
 | 
			
		||||
    scale_value_x = NumericProperty(1)
 | 
			
		||||
    """
 | 
			
		||||
    X-axis value.
 | 
			
		||||
 | 
			
		||||
    :attr:`scale_value_x` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `1`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    scale_value_y = NumericProperty(1)
 | 
			
		||||
    """
 | 
			
		||||
    Y-axis value.
 | 
			
		||||
 | 
			
		||||
    :attr:`scale_value_y` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `1`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    scale_value_z = NumericProperty(1)
 | 
			
		||||
    """
 | 
			
		||||
    Z-axis value.
 | 
			
		||||
 | 
			
		||||
    :attr:`scale_value_z` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `1`.
 | 
			
		||||
    """
 | 
			
		||||
							
								
								
									
										134
									
								
								sbapp/kivymd/uix/behaviors/stencil_behavior.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,134 @@
 | 
			
		||||
"""
 | 
			
		||||
Behaviors/Stencil
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
Base class for controlling the stencil instructions of the widget.
 | 
			
		||||
 | 
			
		||||
.. note:: See `Stencil instructions
 | 
			
		||||
    <https://kivy.org/doc/stable/api-kivy.graphics.stencil_instructions.html>`_
 | 
			
		||||
    for more information.
 | 
			
		||||
 | 
			
		||||
Kivy
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    from kivy.app import App
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    Carousel:
 | 
			
		||||
 | 
			
		||||
        Button:
 | 
			
		||||
            size_hint: .9, .8
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
 | 
			
		||||
            canvas.before:
 | 
			
		||||
                StencilPush
 | 
			
		||||
                RoundedRectangle:
 | 
			
		||||
                    pos: root.pos
 | 
			
		||||
                    size: root.size
 | 
			
		||||
                StencilUse
 | 
			
		||||
            canvas.after:
 | 
			
		||||
                StencilUnUse
 | 
			
		||||
                RoundedRectangle:
 | 
			
		||||
                    pos: root.pos
 | 
			
		||||
                    size: root.size
 | 
			
		||||
                StencilPop
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(App):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
 | 
			
		||||
KivyMD
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.behaviors import StencilBehavior
 | 
			
		||||
    from kivymd.uix.fitimage import FitImage
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    #:import os os
 | 
			
		||||
    #:import images_path kivymd.images_path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    MDCarousel:
 | 
			
		||||
 | 
			
		||||
        StencilImage:
 | 
			
		||||
            size_hint: .9, .8
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            source: os.path.join(images_path, "logo", "kivymd-icon-512.png")
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class StencilImage(FitImage, StencilBehavior):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__all__ = ("StencilBehavior",)
 | 
			
		||||
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.properties import VariableListProperty
 | 
			
		||||
 | 
			
		||||
Builder.load_string(
 | 
			
		||||
    """
 | 
			
		||||
<StencilBehavior>
 | 
			
		||||
    canvas.before:
 | 
			
		||||
        StencilPush
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            pos: root.pos
 | 
			
		||||
            size: root.size
 | 
			
		||||
            # FIXME: Sometimes the radius has the value [], which get a
 | 
			
		||||
            #  `GraphicException: Invalid radius value, must be list of tuples/numerics` error
 | 
			
		||||
            radius: root.radius if root.radius else [0, 0, 0, 0]
 | 
			
		||||
        StencilUse
 | 
			
		||||
    canvas.after:
 | 
			
		||||
        StencilUnUse
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            pos: root.pos
 | 
			
		||||
            size: root.size
 | 
			
		||||
            # FIXME: Sometimes the radius has the value [], which get a
 | 
			
		||||
            #  `GraphicException: Invalid radius value, must be list of tuples/numerics` error
 | 
			
		||||
            radius: root.radius if root.radius else [0, 0, 0, 0]
 | 
			
		||||
        StencilPop
 | 
			
		||||
"""
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StencilBehavior:
 | 
			
		||||
    """Base class for controlling the stencil instructions of the widget."""
 | 
			
		||||
 | 
			
		||||
    radius = VariableListProperty([0], length=4)
 | 
			
		||||
    """
 | 
			
		||||
    Canvas radius.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # Top left corner slice.
 | 
			
		||||
        MDWidget:
 | 
			
		||||
            radius: [25, 0, 0, 0]
 | 
			
		||||
 | 
			
		||||
    :attr:`radius` is an :class:`~kivy.properties.VariableListProperty`
 | 
			
		||||
    and defaults to `[0, 0, 0, 0]`.
 | 
			
		||||
    """
 | 
			
		||||
@ -14,61 +14,104 @@ example:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
.. tabs::
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    .. tab:: Declarative KV style
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
    from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
 | 
			
		||||
    from kivymd.uix.button import MDRectangleFlatButton
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    Screen:
 | 
			
		||||
            from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
        MDBoxLayout:
 | 
			
		||||
            adaptive_size: True
 | 
			
		||||
            pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
            from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
 | 
			
		||||
            from kivymd.uix.button import MDFlatButton
 | 
			
		||||
 | 
			
		||||
            MyToggleButton:
 | 
			
		||||
                text: "Show ads"
 | 
			
		||||
                group: "x"
 | 
			
		||||
            KV = '''
 | 
			
		||||
            MDScreen:
 | 
			
		||||
 | 
			
		||||
            MyToggleButton:
 | 
			
		||||
                text: "Do not show ads"
 | 
			
		||||
                group: "x"
 | 
			
		||||
                MDBoxLayout:
 | 
			
		||||
                    adaptive_size: True
 | 
			
		||||
                    spacing: "12dp"
 | 
			
		||||
                    pos_hint: {"center_x": .5, "center_y": .5}
 | 
			
		||||
 | 
			
		||||
            MyToggleButton:
 | 
			
		||||
                text: "Does not matter"
 | 
			
		||||
                group: "x"
 | 
			
		||||
    '''
 | 
			
		||||
                    MyToggleButton:
 | 
			
		||||
                        text: "Show ads"
 | 
			
		||||
                        group: "x"
 | 
			
		||||
 | 
			
		||||
                    MyToggleButton:
 | 
			
		||||
                        text: "Do not show ads"
 | 
			
		||||
                        group: "x"
 | 
			
		||||
 | 
			
		||||
                    MyToggleButton:
 | 
			
		||||
                        text: "Does not matter"
 | 
			
		||||
                        group: "x"
 | 
			
		||||
            '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class MyToggleButton(MDRectangleFlatButton, MDToggleButton):
 | 
			
		||||
        def __init__(self, **kwargs):
 | 
			
		||||
            super().__init__(**kwargs)
 | 
			
		||||
            self.background_down = self.theme_cls.primary_light
 | 
			
		||||
            class MyToggleButton(MDFlatButton, MDToggleButton):
 | 
			
		||||
                def __init__(self, *args, **kwargs):
 | 
			
		||||
                    super().__init__(*args, **kwargs)
 | 
			
		||||
                    self.background_down = self.theme_cls.primary_color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
        def build(self):
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
            class Test(MDApp):
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                    return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
            Test().run()
 | 
			
		||||
 | 
			
		||||
    .. tab:: Declarative python style
 | 
			
		||||
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
            from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
 | 
			
		||||
            from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
            from kivymd.uix.button import MDFlatButton
 | 
			
		||||
            from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            class MyToggleButton(MDFlatButton, MDToggleButton):
 | 
			
		||||
                def __init__(self, *args, **kwargs):
 | 
			
		||||
                    super().__init__(*args, **kwargs)
 | 
			
		||||
                    self.background_down = self.theme_cls.primary_color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            class Test(MDApp):
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                    return (
 | 
			
		||||
                        MDScreen(
 | 
			
		||||
                            MDBoxLayout(
 | 
			
		||||
                                MyToggleButton(
 | 
			
		||||
                                    text="Show ads",
 | 
			
		||||
                                    group="x",
 | 
			
		||||
                                ),
 | 
			
		||||
                                MyToggleButton(
 | 
			
		||||
                                    text="Do not show ads",
 | 
			
		||||
                                    group="x",
 | 
			
		||||
                                ),
 | 
			
		||||
                                MyToggleButton(
 | 
			
		||||
                                    text="Does not matter",
 | 
			
		||||
                                    group="x",
 | 
			
		||||
                                ),
 | 
			
		||||
                                adaptive_size=True,
 | 
			
		||||
                                spacing="12dp",
 | 
			
		||||
                                pos_hint={"center_x": .5, "center_y": .5},
 | 
			
		||||
                            ),
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            Test().run()
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toggle-button-1.gif
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    class MyToggleButton(MDFillRoundFlatButton, MDToggleButton):
 | 
			
		||||
        def __init__(self, **kwargs):
 | 
			
		||||
        self.background_down = MDApp.get_running_app().theme_cls.primary_dark
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toggle-button-2.gif
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
You can inherit the ``MyToggleButton`` class only from the following classes
 | 
			
		||||
----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@ -88,6 +131,7 @@ from kivy.properties import BooleanProperty, ColorProperty
 | 
			
		||||
from kivy.uix.behaviors import ToggleButtonBehavior
 | 
			
		||||
 | 
			
		||||
from kivymd.uix.button import (
 | 
			
		||||
    ButtonContentsIconText,
 | 
			
		||||
    MDFillRoundFlatButton,
 | 
			
		||||
    MDFillRoundFlatIconButton,
 | 
			
		||||
    MDFlatButton,
 | 
			
		||||
@ -149,7 +193,8 @@ class MDToggleButton(ToggleButtonBehavior):
 | 
			
		||||
        # Do the object inherited from the "supported" buttons?
 | 
			
		||||
        if not issubclass(self.__class__, classinfo):
 | 
			
		||||
            raise ValueError(
 | 
			
		||||
                f"Class {self.__class__} must be inherited from one of the classes in the list {classinfo}"
 | 
			
		||||
                f"Class {self.__class__} must be inherited from one of the "
 | 
			
		||||
                f"classes in the list {classinfo}"
 | 
			
		||||
            )
 | 
			
		||||
        if (
 | 
			
		||||
            not self.background_normal
 | 
			
		||||
@ -165,10 +210,12 @@ class MDToggleButton(ToggleButtonBehavior):
 | 
			
		||||
            ):
 | 
			
		||||
                self.__is_filled = True
 | 
			
		||||
                self.background_normal = self.theme_cls.primary_color
 | 
			
		||||
            # If not the background_normal must be the same as the inherited one:
 | 
			
		||||
            # If not background_normal must be the same as the inherited one.
 | 
			
		||||
            else:
 | 
			
		||||
                self.background_normal = self.md_bg_color[:]
 | 
			
		||||
        # If no background_down is setted:
 | 
			
		||||
                self.background_normal = (
 | 
			
		||||
                    self.md_bg_color[:] if self.md_bg_color else (0, 0, 0, 0)
 | 
			
		||||
                )
 | 
			
		||||
        # If no background_down is setter.
 | 
			
		||||
        if (
 | 
			
		||||
            not self.background_down
 | 
			
		||||
        ):  # This means that if the value == [] or None will return True.
 | 
			
		||||
@ -200,3 +247,6 @@ class MDToggleButton(ToggleButtonBehavior):
 | 
			
		||||
            ):  # If the background is transparent, the font color must be the
 | 
			
		||||
                # primary color.
 | 
			
		||||
                self.text_color = self.font_color_normal
 | 
			
		||||
 | 
			
		||||
        if issubclass(self.__class__, ButtonContentsIconText):
 | 
			
		||||
            self.icon_color = self.text_color
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
#:import sm kivy.uix.screenmanager
 | 
			
		||||
#:import STANDARD_INCREMENT kivymd.material_resources.STANDARD_INCREMENT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +8,7 @@
 | 
			
		||||
 | 
			
		||||
    ScreenManager:
 | 
			
		||||
        id: tab_manager
 | 
			
		||||
        transition: sm.FadeTransition(duration=.2)
 | 
			
		||||
        transition: root.transition(duration=root.transition_duration)
 | 
			
		||||
        on_current:
 | 
			
		||||
            root.dispatch( \
 | 
			
		||||
            "on_switch_tabs", \
 | 
			
		||||
@ -96,7 +95,7 @@
 | 
			
		||||
                    radius: [16,]
 | 
			
		||||
                    size: root._selected_region_width, dp(32)
 | 
			
		||||
                    pos:
 | 
			
		||||
                        self.center_x - self.width - dp(8), \
 | 
			
		||||
                        self.center_x - root._selected_region_width / 2, \
 | 
			
		||||
                        self.center_y - (dp(16))
 | 
			
		||||
 | 
			
		||||
        MDLabel:
 | 
			
		||||
 | 
			
		||||
@ -62,59 +62,120 @@ For ease of understanding, this code works like this:
 | 
			
		||||
Example
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
.. tabs::
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
    .. tab:: Declarative KV style
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
            from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Test(MDApp):
 | 
			
		||||
            class Test(MDApp):
 | 
			
		||||
 | 
			
		||||
        def build(self):
 | 
			
		||||
            self.theme_cls.material_style = "M3"
 | 
			
		||||
            return Builder.load_string(
 | 
			
		||||
                '''
 | 
			
		||||
    MDScreen:
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.material_style = "M3"
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    return Builder.load_string(
 | 
			
		||||
                        '''
 | 
			
		||||
            MDScreen:
 | 
			
		||||
 | 
			
		||||
        MDBottomNavigation:
 | 
			
		||||
            panel_color: "#eeeaea"
 | 
			
		||||
            selected_color_background: "#97ecf8"
 | 
			
		||||
            text_color_active: 0, 0, 0, 1
 | 
			
		||||
                MDBottomNavigation:
 | 
			
		||||
                    #panel_color: "#eeeaea"
 | 
			
		||||
                    selected_color_background: "orange"
 | 
			
		||||
                    text_color_active: "lightgrey"
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: 'screen 1'
 | 
			
		||||
                text: 'Mail'
 | 
			
		||||
                icon: 'gmail'
 | 
			
		||||
                badge_icon: "numeric-10"
 | 
			
		||||
                    MDBottomNavigationItem:
 | 
			
		||||
                        name: 'screen 1'
 | 
			
		||||
                        text: 'Mail'
 | 
			
		||||
                        icon: 'gmail'
 | 
			
		||||
                        badge_icon: "numeric-10"
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: 'Mail'
 | 
			
		||||
                    halign: 'center'
 | 
			
		||||
                        MDLabel:
 | 
			
		||||
                            text: 'Mail'
 | 
			
		||||
                            halign: 'center'
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: 'screen 2'
 | 
			
		||||
                text: 'Discord'
 | 
			
		||||
                icon: 'discord'
 | 
			
		||||
                badge_icon: "numeric-5"
 | 
			
		||||
                    MDBottomNavigationItem:
 | 
			
		||||
                        name: 'screen 2'
 | 
			
		||||
                        text: 'Twitter'
 | 
			
		||||
                        icon: 'twitter'
 | 
			
		||||
                        badge_icon: "numeric-5"
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: 'Discord'
 | 
			
		||||
                    halign: 'center'
 | 
			
		||||
                        MDLabel:
 | 
			
		||||
                            text: 'Twitter'
 | 
			
		||||
                            halign: 'center'
 | 
			
		||||
 | 
			
		||||
            MDBottomNavigationItem:
 | 
			
		||||
                name: 'screen 3'
 | 
			
		||||
                text: 'LinkedIN'
 | 
			
		||||
                icon: 'linkedin'
 | 
			
		||||
                    MDBottomNavigationItem:
 | 
			
		||||
                        name: 'screen 3'
 | 
			
		||||
                        text: 'LinkedIN'
 | 
			
		||||
                        icon: 'linkedin'
 | 
			
		||||
 | 
			
		||||
                MDLabel:
 | 
			
		||||
                    text: 'LinkedIN'
 | 
			
		||||
                    halign: 'center'
 | 
			
		||||
    '''
 | 
			
		||||
            )
 | 
			
		||||
                        MDLabel:
 | 
			
		||||
                            text: 'LinkedIN'
 | 
			
		||||
                            halign: 'center'
 | 
			
		||||
            '''
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Test().run()
 | 
			
		||||
            Test().run()
 | 
			
		||||
 | 
			
		||||
    .. tab:: Declarative python style
 | 
			
		||||
 | 
			
		||||
        .. code-block:: python
 | 
			
		||||
 | 
			
		||||
            from kivymd.app import MDApp
 | 
			
		||||
            from kivymd.uix.bottomnavigation import MDBottomNavigation, MDBottomNavigationItem
 | 
			
		||||
            from kivymd.uix.label import MDLabel
 | 
			
		||||
            from kivymd.uix.screen import MDScreen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            class Test(MDApp):
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.material_style = "M3"
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    return (
 | 
			
		||||
                        MDScreen(
 | 
			
		||||
                            MDBottomNavigation(
 | 
			
		||||
                                MDBottomNavigationItem(
 | 
			
		||||
                                    MDLabel(
 | 
			
		||||
                                        text='Mail',
 | 
			
		||||
                                        halign='center',
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    name='screen 1',
 | 
			
		||||
                                    text='Mail',
 | 
			
		||||
                                    icon='gmail',
 | 
			
		||||
                                    badge_icon="numeric-10",
 | 
			
		||||
                                ),
 | 
			
		||||
                                MDBottomNavigationItem(
 | 
			
		||||
                                    MDLabel(
 | 
			
		||||
                                        text='Twitter',
 | 
			
		||||
                                        halign='center',
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    name='screen 1',
 | 
			
		||||
                                    text='Twitter',
 | 
			
		||||
                                    icon='twitter',
 | 
			
		||||
                                    badge_icon="numeric-10",
 | 
			
		||||
                                ),
 | 
			
		||||
                                MDBottomNavigationItem(
 | 
			
		||||
                                    MDLabel(
 | 
			
		||||
                                        text='LinkedIN',
 | 
			
		||||
                                        halign='center',
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    name='screen 1',
 | 
			
		||||
                                    text='LinkedIN',
 | 
			
		||||
                                    icon='linkedin',
 | 
			
		||||
                                    badge_icon="numeric-10",
 | 
			
		||||
                                ),
 | 
			
		||||
                                selected_color_background="orange",
 | 
			
		||||
                                text_color_active="lightgrey",
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            Test().run()
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/bottom-navigation.gif
 | 
			
		||||
    :align: center
 | 
			
		||||
@ -192,13 +253,13 @@ from kivy.properties import (
 | 
			
		||||
)
 | 
			
		||||
from kivy.uix.behaviors import ButtonBehavior
 | 
			
		||||
from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
from kivy.uix.screenmanager import ScreenManagerException
 | 
			
		||||
from kivy.uix.screenmanager import FadeTransition, ScreenManagerException
 | 
			
		||||
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.material_resources import STANDARD_INCREMENT
 | 
			
		||||
from kivymd.theming import ThemableBehavior, ThemeManager
 | 
			
		||||
from kivymd.uix.anchorlayout import MDAnchorLayout
 | 
			
		||||
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
 | 
			
		||||
from kivymd.uix.behaviors import CommonElevationBehavior, DeclarativeBehavior
 | 
			
		||||
from kivymd.uix.behaviors.backgroundcolor_behavior import (
 | 
			
		||||
    SpecificBackgroundColorBehavior,
 | 
			
		||||
)
 | 
			
		||||
@ -364,8 +425,8 @@ class MDTab(MDScreen, ThemableBehavior):
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.index = 0
 | 
			
		||||
        self.parent_widget = None
 | 
			
		||||
        self.register_event_type("on_tab_touch_down")
 | 
			
		||||
@ -407,6 +468,31 @@ class MDBottomNavigationItem(MDTab):
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def animate_header(
 | 
			
		||||
        self, bottom_navigation_object, bottom_navigation_header_object
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        if bottom_navigation_object.use_text:
 | 
			
		||||
            Animation(_label_font_size=sp(12), d=0.1).start(
 | 
			
		||||
                bottom_navigation_object.previous_tab.header
 | 
			
		||||
            )
 | 
			
		||||
        Animation(
 | 
			
		||||
            _selected_region_width=0,
 | 
			
		||||
            t="in_out_sine",
 | 
			
		||||
            d=0,
 | 
			
		||||
        ).start(bottom_navigation_header_object)
 | 
			
		||||
        Animation(
 | 
			
		||||
            _text_color_normal=bottom_navigation_header_object.text_color_normal
 | 
			
		||||
            if bottom_navigation_object.previous_tab.header.text_color_normal
 | 
			
		||||
            != [1, 1, 1, 1]
 | 
			
		||||
            else self.theme_cls.disabled_hint_text_color,
 | 
			
		||||
            d=0.1,
 | 
			
		||||
        ).start(bottom_navigation_object.previous_tab.header)
 | 
			
		||||
        bottom_navigation_object.previous_tab.header.active = False
 | 
			
		||||
        self.header.active = True
 | 
			
		||||
 | 
			
		||||
    def on_tab_press(self, *args) -> None:
 | 
			
		||||
        """Called when clicking on a panel item."""
 | 
			
		||||
 | 
			
		||||
@ -414,28 +500,13 @@ class MDBottomNavigationItem(MDTab):
 | 
			
		||||
        bottom_navigation_header_object = (
 | 
			
		||||
            bottom_navigation_object.previous_tab.header
 | 
			
		||||
        )
 | 
			
		||||
        bottom_navigation_object.ids.tab_manager.current = self.name
 | 
			
		||||
 | 
			
		||||
        if bottom_navigation_object.previous_tab is not self:
 | 
			
		||||
            if bottom_navigation_object.use_text:
 | 
			
		||||
                Animation(_label_font_size=sp(12), d=0.1).start(
 | 
			
		||||
                    bottom_navigation_object.previous_tab.header
 | 
			
		||||
                )
 | 
			
		||||
            Animation(
 | 
			
		||||
                _selected_region_width=0,
 | 
			
		||||
                t="in_out_sine",
 | 
			
		||||
                d=0,
 | 
			
		||||
            ).start(bottom_navigation_header_object)
 | 
			
		||||
            Animation(
 | 
			
		||||
                _text_color_normal=bottom_navigation_header_object.text_color_normal
 | 
			
		||||
                if bottom_navigation_object.previous_tab.header.text_color_normal
 | 
			
		||||
                != [1, 1, 1, 1]
 | 
			
		||||
                else self.theme_cls.disabled_hint_text_color,
 | 
			
		||||
                d=0.1,
 | 
			
		||||
            ).start(bottom_navigation_object.previous_tab.header)
 | 
			
		||||
            bottom_navigation_object.previous_tab.header.active = False
 | 
			
		||||
            self.header.active = True
 | 
			
		||||
        bottom_navigation_object.previous_tab = self
 | 
			
		||||
            self.animate_header(
 | 
			
		||||
                bottom_navigation_object, bottom_navigation_header_object
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        super().on_tab_press(*args)
 | 
			
		||||
 | 
			
		||||
    def on_disabled(
 | 
			
		||||
        self, instance_bottom_navigation_item, disabled_value: bool
 | 
			
		||||
@ -463,7 +534,7 @@ class TabbedPanelBase(
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    previous_tab = ObjectProperty()
 | 
			
		||||
    previous_tab = ObjectProperty(None, aloownone=True)
 | 
			
		||||
    """
 | 
			
		||||
    :attr:`previous_tab` is an :class:`~MDTab` and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
@ -479,7 +550,7 @@ class TabbedPanelBase(
 | 
			
		||||
    tabs = ListProperty()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
class MDBottomNavigation(DeclarativeBehavior, TabbedPanelBase):
 | 
			
		||||
    """
 | 
			
		||||
    A bottom navigation that is implemented by delegating all items to a
 | 
			
		||||
    :class:`~kivy.uix.screenmanager.ScreenManager`.
 | 
			
		||||
@ -492,6 +563,26 @@ class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
        .. versionadded:: 1.0.0
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    transition = ObjectProperty(FadeTransition)
 | 
			
		||||
    """
 | 
			
		||||
    Transition animation of bottom navigation screen manager.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`transition` is an :class:`~kivy.properties.ObjectProperty`
 | 
			
		||||
    and defaults to `FadeTransition`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    transition_duration = NumericProperty(0.2)
 | 
			
		||||
    """
 | 
			
		||||
    Duration animation of bottom navigation screen manager.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`transition_duration` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `0.2`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    text_color_normal = ColorProperty([1, 1, 1, 1])
 | 
			
		||||
    """
 | 
			
		||||
    Text color of the label when it is not selected.
 | 
			
		||||
@ -594,14 +685,15 @@ class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
    and defaults to `False`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    widget_index = NumericProperty(0)
 | 
			
		||||
 | 
			
		||||
    # Text active color if it is selected.
 | 
			
		||||
    _active_color = ColorProperty([1, 1, 1, 1])
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
        self.register_event_type("on_switch_tabs")
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.previous_tab = None
 | 
			
		||||
        self.widget_index = 0
 | 
			
		||||
        self.register_event_type("on_switch_tabs")
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.theme_cls.bind(material_style=self.refresh_tabs)
 | 
			
		||||
        Window.bind(on_resize=self.on_resize)
 | 
			
		||||
        Clock.schedule_once(lambda x: self.on_resize())
 | 
			
		||||
@ -660,8 +752,11 @@ class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
    def on_selected_color_background(
 | 
			
		||||
        self, instance_bottom_navigation, color: list
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        for tab in self.ids.tab_bar.children:
 | 
			
		||||
            tab.selected_color_background = color
 | 
			
		||||
        def on_selected_color_background(*args):
 | 
			
		||||
            for tab in self.ids.tab_bar.children:
 | 
			
		||||
                tab.selected_color_background = color
 | 
			
		||||
 | 
			
		||||
        Clock.schedule_once(on_selected_color_background)
 | 
			
		||||
 | 
			
		||||
    def on_use_text(
 | 
			
		||||
        self, instance_bottom_navigation, use_text_value: bool
 | 
			
		||||
@ -698,12 +793,15 @@ class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
    def on_text_color_active(
 | 
			
		||||
        self, instance_bottom_navigation, color: list
 | 
			
		||||
    ) -> None:
 | 
			
		||||
        MDBottomNavigationHeader.text_color_active = color
 | 
			
		||||
        self.text_color_active = color
 | 
			
		||||
        for tab in self.ids.tab_bar.children:
 | 
			
		||||
            tab.text_color_active = color
 | 
			
		||||
            if tab.active:
 | 
			
		||||
                tab._text_color_normal = color
 | 
			
		||||
        def on_text_color_active(*args):
 | 
			
		||||
            MDBottomNavigationHeader.text_color_active = color
 | 
			
		||||
            self.text_color_active = color
 | 
			
		||||
            for tab in self.ids.tab_bar.children:
 | 
			
		||||
                tab.text_color_active = color
 | 
			
		||||
                if tab.active:
 | 
			
		||||
                    tab._text_color_normal = color
 | 
			
		||||
 | 
			
		||||
        Clock.schedule_once(on_text_color_active)
 | 
			
		||||
 | 
			
		||||
    def on_switch_tabs(self, bottom_navigation_item, name_tab: str) -> None:
 | 
			
		||||
        """
 | 
			
		||||
@ -759,8 +857,6 @@ class MDBottomNavigation(TabbedPanelBase):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBottomNavigationBar(
 | 
			
		||||
    ThemableBehavior,
 | 
			
		||||
    FakeRectangularElevationBehavior,
 | 
			
		||||
    MDFloatLayout,
 | 
			
		||||
    ThemableBehavior, CommonElevationBehavior, MDFloatLayout
 | 
			
		||||
):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ Usage :class:`~MDListBottomSheet`
 | 
			
		||||
        MDTopAppBar:
 | 
			
		||||
            title: "Example BottomSheet"
 | 
			
		||||
            pos_hint: {"top": 1}
 | 
			
		||||
            elevation: 10
 | 
			
		||||
            elevation: 4
 | 
			
		||||
 | 
			
		||||
        MDRaisedButton:
 | 
			
		||||
            text: "Open list bottom sheet"
 | 
			
		||||
@ -94,7 +94,7 @@ which will be used as an icon to the left of the item:
 | 
			
		||||
        MDTopAppBar:
 | 
			
		||||
            title: 'Example BottomSheet'
 | 
			
		||||
            pos_hint: {"top": 1}
 | 
			
		||||
            elevation: 10
 | 
			
		||||
            elevation: 4
 | 
			
		||||
 | 
			
		||||
        MDRaisedButton:
 | 
			
		||||
            text: "Open grid bottom sheet"
 | 
			
		||||
@ -180,7 +180,7 @@ which will be used as an icon to the left of the item:
 | 
			
		||||
        MDTopAppBar:
 | 
			
		||||
            title: 'Example BottomSheet'
 | 
			
		||||
            pos_hint: {"top": 1}
 | 
			
		||||
            elevation: 10
 | 
			
		||||
            elevation: 4
 | 
			
		||||
 | 
			
		||||
        MDRaisedButton:
 | 
			
		||||
            text: "Open custom bottom sheet"
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ with some widget properties. For example:
 | 
			
		||||
BoxLayout
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
.. code-block::
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    BoxLayout:
 | 
			
		||||
        size_hint_y: None
 | 
			
		||||
@ -24,7 +24,7 @@ BoxLayout
 | 
			
		||||
MDBoxLayout
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
.. code-block::
 | 
			
		||||
.. code-block:: kv
 | 
			
		||||
 | 
			
		||||
    MDBoxLayout:
 | 
			
		||||
        adaptive_height: True
 | 
			
		||||
@ -88,7 +88,13 @@ __all__ = ("MDBoxLayout",)
 | 
			
		||||
from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
 | 
			
		||||
from kivymd.uix import MDAdaptiveWidget
 | 
			
		||||
from kivymd.uix.behaviors import DeclarativeBehavior
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDBoxLayout(BoxLayout, MDAdaptiveWidget):
 | 
			
		||||
    pass
 | 
			
		||||
class MDBoxLayout(DeclarativeBehavior, BoxLayout, MDAdaptiveWidget):
 | 
			
		||||
    """
 | 
			
		||||
    Box layout class.
 | 
			
		||||
 | 
			
		||||
    For more information, see in the
 | 
			
		||||
    :class:`~kivy.uix.boxlayout.BoxLayout` class documentation.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
# NOQA F401
 | 
			
		||||
from .button import (
 | 
			
		||||
    BaseButton,
 | 
			
		||||
    ButtonContentsIconText,
 | 
			
		||||
    MDFillRoundFlatButton,
 | 
			
		||||
    MDFillRoundFlatIconButton,
 | 
			
		||||
    MDFlatButton,
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,9 @@
 | 
			
		||||
        Clear
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba:
 | 
			
		||||
                (self._md_bg_color or [0.0, 0.0, 0.0, 0.0]) \
 | 
			
		||||
                self._md_bg_color \
 | 
			
		||||
                if not self.disabled else \
 | 
			
		||||
                (self._md_bg_color_disabled or [0.0, 0.0, 0.0, 0.0])
 | 
			
		||||
                self._md_bg_color_disabled
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            size: self.size
 | 
			
		||||
            pos: self.pos
 | 
			
		||||
@ -13,19 +13,17 @@
 | 
			
		||||
            radius: [root._radius, ]
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba:
 | 
			
		||||
                root._line_color or [0.0, 0.0, 0.0, 0.0] \
 | 
			
		||||
                root._line_color \
 | 
			
		||||
                if not root.disabled else \
 | 
			
		||||
                ( \
 | 
			
		||||
                root._line_color_disabled \
 | 
			
		||||
                or self._disabled_color \
 | 
			
		||||
                or [0.0, 0.0, 0.0, 0.0] \
 | 
			
		||||
                )
 | 
			
		||||
                (root._line_color_disabled or self._disabled_color)
 | 
			
		||||
        Line:
 | 
			
		||||
            width: root.line_width
 | 
			
		||||
            rounded_rectangle:
 | 
			
		||||
                (self.x, self.y, self.width, self.height, \
 | 
			
		||||
                ( \
 | 
			
		||||
                self.x, self.y, self.width, self.height, \
 | 
			
		||||
                root._radius, root._radius, root._radius, root._radius, \
 | 
			
		||||
                self.height)
 | 
			
		||||
                self.height \
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
    size_hint: None, None
 | 
			
		||||
    anchor_x: root.halign
 | 
			
		||||
@ -33,21 +31,28 @@
 | 
			
		||||
    _round_rad: [self._radius] * 4
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<ButtonContentsText>
 | 
			
		||||
    lbl_txt: lbl_txt
 | 
			
		||||
    width:
 | 
			
		||||
        max(root._min_width, \
 | 
			
		||||
        root.padding[0] + lbl_txt.texture_size[0] + root.padding[2])
 | 
			
		||||
        max( \
 | 
			
		||||
        root._min_width, \
 | 
			
		||||
        root.padding[0] + lbl_txt.texture_size[0] + root.padding[2] \
 | 
			
		||||
        )
 | 
			
		||||
    size_hint_min_x:
 | 
			
		||||
        max(root._min_width, \
 | 
			
		||||
        root.padding[0] + lbl_txt.texture_size[0] + root.padding[2])
 | 
			
		||||
        max( \
 | 
			
		||||
        root._min_width, \
 | 
			
		||||
        root.padding[0] + lbl_txt.texture_size[0] + root.padding[2] \
 | 
			
		||||
        )
 | 
			
		||||
    height:
 | 
			
		||||
        max(root._min_height, \
 | 
			
		||||
        root.padding[1] + lbl_txt.texture_size[1] + root.padding[3])
 | 
			
		||||
        max( \
 | 
			
		||||
        root._min_height, \
 | 
			
		||||
        root.padding[1] + lbl_txt.texture_size[1] + root.padding[3] \
 | 
			
		||||
        )
 | 
			
		||||
    size_hint_min_y:
 | 
			
		||||
        max(root._min_height, \
 | 
			
		||||
        root.padding[1] + lbl_txt.texture_size[1] + root.padding[3])
 | 
			
		||||
        max( \
 | 
			
		||||
        root._min_height, \
 | 
			
		||||
        root.padding[1] + lbl_txt.texture_size[1] + root.padding[3] \
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    MDLabel:
 | 
			
		||||
        id: lbl_txt
 | 
			
		||||
@ -84,7 +89,10 @@
 | 
			
		||||
            #  This is only a temporary fix and does not fix the cause of the error.
 | 
			
		||||
            (root._icon_color if root._icon_color else root.theme_cls.text_color) \
 | 
			
		||||
            if not root.disabled else \
 | 
			
		||||
            root.theme_cls.disabled_hint_text_color
 | 
			
		||||
            root.theme_cls.disabled_hint_text_color \
 | 
			
		||||
            if not root.disabled_color else \
 | 
			
		||||
            root.disabled_color
 | 
			
		||||
 | 
			
		||||
        on_icon:
 | 
			
		||||
            if self.icon not in md_icons.keys(): self.size_hint = (1, 1)
 | 
			
		||||
        theme_text_color: root._theme_icon_color
 | 
			
		||||
@ -131,7 +139,7 @@
 | 
			
		||||
        id: box
 | 
			
		||||
        adaptive_size: True
 | 
			
		||||
        padding: 0
 | 
			
		||||
        spacing: "4dp"
 | 
			
		||||
        spacing: "8dp"
 | 
			
		||||
 | 
			
		||||
        MDIcon:
 | 
			
		||||
            id: lbl_ic
 | 
			
		||||
@ -193,48 +201,21 @@
 | 
			
		||||
            radius: [self.height / 2]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<BaseFloatingRootButton>
 | 
			
		||||
<MDFloatingRootButton>
 | 
			
		||||
    theme_text_color: "Custom"
 | 
			
		||||
    md_bg_color: self.theme_cls.primary_color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDFloatingLabel>
 | 
			
		||||
    padding_x: "8dp"
 | 
			
		||||
    padding_y: "8dp"
 | 
			
		||||
    adaptive_size: True
 | 
			
		||||
    theme_text_color: "Custom"
 | 
			
		||||
 | 
			
		||||
    canvas.before:
 | 
			
		||||
        PushMatrix
 | 
			
		||||
        Rotate:
 | 
			
		||||
            angle: self._angle
 | 
			
		||||
            axis: (0, 0, 1)
 | 
			
		||||
            origin: self.center
 | 
			
		||||
    canvas.after:
 | 
			
		||||
        PopMatrix
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# FIXME: Use :class:`~kivymd.uix.boxlayout.MDBoxLayout` instead
 | 
			
		||||
#  :class:`~kivy.uix.boxlayout.BoxLayout`.
 | 
			
		||||
<BaseFloatingLabel>
 | 
			
		||||
    size_hint: None, None
 | 
			
		||||
    padding: "8dp", "4dp", "8dp", "4dp"
 | 
			
		||||
    height: label.texture_size[1] + self.padding[1] * 2
 | 
			
		||||
    width: label.texture_size[0] + self.padding[0] * 2
 | 
			
		||||
    elevation: 10
 | 
			
		||||
 | 
			
		||||
    # TODO: Use `md_bg_color` and `radius` instead `canvasю
 | 
			
		||||
    canvas:
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba:
 | 
			
		||||
                self.theme_cls.primary_color \
 | 
			
		||||
                if not root.bg_color else \
 | 
			
		||||
                root.bg_color
 | 
			
		||||
            rgba: self.bg_color
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            pos: self.pos
 | 
			
		||||
            size: self.size
 | 
			
		||||
            radius: [5]
 | 
			
		||||
 | 
			
		||||
    Label:
 | 
			
		||||
        id: label
 | 
			
		||||
        markup: True
 | 
			
		||||
        text: root.text
 | 
			
		||||
        size_hint: None, None
 | 
			
		||||
        size: self.texture_size
 | 
			
		||||
        color:
 | 
			
		||||
            root.theme_cls.text_color \
 | 
			
		||||
            if not root.text_color else \
 | 
			
		||||
            root.text_color
 | 
			
		||||
            pos: self.pos
 | 
			
		||||
            radius: self.radius
 | 
			
		||||
 | 
			
		||||
@ -2,17 +2,6 @@
 | 
			
		||||
    md_bg_color: app.theme_cls.divider_color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDCard>
 | 
			
		||||
    canvas.before:
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba: self.md_bg_color
 | 
			
		||||
        RoundedRectangle:
 | 
			
		||||
            size: self.size
 | 
			
		||||
            pos: self.pos
 | 
			
		||||
            radius: root.radius
 | 
			
		||||
            source: root.background
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDSeparator>
 | 
			
		||||
    md_bg_color:
 | 
			
		||||
        self.theme_cls.divider_color \
 | 
			
		||||
 | 
			
		||||
@ -57,8 +57,10 @@ MDCarousel
 | 
			
		||||
from kivy.animation import Animation
 | 
			
		||||
from kivy.uix.carousel import Carousel
 | 
			
		||||
 | 
			
		||||
from kivymd.uix.behaviors import DeclarativeBehavior
 | 
			
		||||
 | 
			
		||||
class MDCarousel(Carousel):
 | 
			
		||||
 | 
			
		||||
class MDCarousel(DeclarativeBehavior, Carousel):
 | 
			
		||||
    """
 | 
			
		||||
    based on kivy's carousel.
 | 
			
		||||
 | 
			
		||||
@ -68,8 +70,8 @@ class MDCarousel(Carousel):
 | 
			
		||||
 | 
			
		||||
    _scrolling = False
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.register_event_type("on_slide_progress")
 | 
			
		||||
        self.register_event_type("on_slide_complete")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
from .chip import MDChip, MDChooseChip  # NOQA F401
 | 
			
		||||
from .chip import MDChip  # NOQA F401
 | 
			
		||||
 | 
			
		||||
@ -132,7 +132,7 @@ Use with elevation
 | 
			
		||||
        icon_right: "close-circle-outline"
 | 
			
		||||
        line_color: app.theme_cls.disabled_hint_text_color
 | 
			
		||||
        md_bg_color: 1, 0, 0, .5
 | 
			
		||||
        elevation: 12
 | 
			
		||||
        elevation: 4
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-elevation.png
 | 
			
		||||
    :align: center
 | 
			
		||||
@ -304,7 +304,6 @@ __all__ = ("MDChip",)
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from kivy import Logger
 | 
			
		||||
from kivy.animation import Animation
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.metrics import dp
 | 
			
		||||
@ -314,14 +313,13 @@ from kivy.uix.behaviors import ButtonBehavior
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.theming import ThemableBehavior
 | 
			
		||||
from kivymd.uix.behaviors import (
 | 
			
		||||
    FakeRectangularElevationBehavior,
 | 
			
		||||
    CommonElevationBehavior,
 | 
			
		||||
    RectangularRippleBehavior,
 | 
			
		||||
    ScaleBehavior,
 | 
			
		||||
    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"
 | 
			
		||||
@ -330,12 +328,12 @@ with open(
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDChip(
 | 
			
		||||
    MDBoxLayout,
 | 
			
		||||
    ThemableBehavior,
 | 
			
		||||
    RectangularRippleBehavior,
 | 
			
		||||
    FakeRectangularElevationBehavior,
 | 
			
		||||
    TouchBehavior,
 | 
			
		||||
    ButtonBehavior,
 | 
			
		||||
    MDBoxLayout,
 | 
			
		||||
    CommonElevationBehavior,
 | 
			
		||||
    TouchBehavior,
 | 
			
		||||
):
 | 
			
		||||
    text = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
@ -345,17 +343,6 @@ class MDChip(
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    icon = StringProperty("checkbox-blank-circle", deprecated=True)
 | 
			
		||||
    """
 | 
			
		||||
    Chip icon.
 | 
			
		||||
 | 
			
		||||
    .. deprecated:: 1.0.0
 | 
			
		||||
        Use :attr:`icon_right` and :attr:`icon_left` instead.
 | 
			
		||||
 | 
			
		||||
    :attr:`icon` is an :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    and defaults to `'checkbox-blank-circle'`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    icon_left = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Chip left icon.
 | 
			
		||||
@ -376,16 +363,6 @@ class MDChip(
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    color = ColorProperty(None, deprecated=True)
 | 
			
		||||
    """
 | 
			
		||||
    Chip color in ``rgba`` format.
 | 
			
		||||
 | 
			
		||||
    .. deprecated:: 1.0.0
 | 
			
		||||
 | 
			
		||||
    :attr:`color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    text_color = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Chip's text color in ``rgba`` format.
 | 
			
		||||
@ -394,17 +371,6 @@ class MDChip(
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    icon_color = ColorProperty(None, deprecated=True)
 | 
			
		||||
    """
 | 
			
		||||
    Chip's icon color in ``rgba`` format.
 | 
			
		||||
 | 
			
		||||
    .. deprecated:: 1.0.0
 | 
			
		||||
        Use :attr:`icon_right_color` and :attr:`icon_left_color` instead.
 | 
			
		||||
 | 
			
		||||
    :attr:`icon_color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    icon_right_color = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Chip's right icon color in ``rgba`` format.
 | 
			
		||||
@ -435,26 +401,6 @@ class MDChip(
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    check = BooleanProperty(False, deprecated=True)
 | 
			
		||||
    """
 | 
			
		||||
    If `True`, a checkmark is added to the left when touch to the chip.
 | 
			
		||||
 | 
			
		||||
    .. deprecated:: 1.0.0
 | 
			
		||||
 | 
			
		||||
    :attr:`check` is an :class:`~kivy.properties.BooleanProperty`
 | 
			
		||||
    and defaults to `False`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    selected_chip_color = ColorProperty(None, deprecated=True)
 | 
			
		||||
    """
 | 
			
		||||
    The color of the chip that is currently selected in ``rgba`` format.
 | 
			
		||||
 | 
			
		||||
    .. deprecated:: 1.0.0
 | 
			
		||||
 | 
			
		||||
    :attr:`selected_chip_color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    active = BooleanProperty(False)
 | 
			
		||||
    """
 | 
			
		||||
    Whether the check is marked or not.
 | 
			
		||||
@ -508,16 +454,7 @@ class MDChip(
 | 
			
		||||
            self.active = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDChooseChip(MDStackLayout):
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
        Logger.warning(
 | 
			
		||||
            "MDChooseChip: "
 | 
			
		||||
            "class is deprecated and will be removed in a future version"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDScalableCheckIcon(MDIcon, ScaleWidget):
 | 
			
		||||
class MDScalableCheckIcon(MDIcon, ScaleBehavior):
 | 
			
		||||
    pos_hint = {"center_y": 0.5}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
Controllers/WindowController
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
Modules and classes that implement useful methods for getting information
 | 
			
		||||
about the state of the current application window.
 | 
			
		||||
 | 
			
		||||
@ -33,16 +35,35 @@ Controlling the resizing direction of the application window
 | 
			
		||||
 | 
			
		||||
from kivy.core.window import Window
 | 
			
		||||
from kivy.core.window.window_sdl2 import WindowSDL
 | 
			
		||||
from kivy.metrics import dp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WindowController:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.window_resizing_direction = "unknown"
 | 
			
		||||
        self.real_device_type = "unknown"
 | 
			
		||||
        self.__width = Window.width
 | 
			
		||||
        Window.bind(on_resize=self._on_resize)
 | 
			
		||||
 | 
			
		||||
    def on_size(self, instance, size: list) -> None:
 | 
			
		||||
        """Called when the application screen size changes."""
 | 
			
		||||
 | 
			
		||||
        window_width = size[0]
 | 
			
		||||
 | 
			
		||||
        if window_width < dp(500):
 | 
			
		||||
            self.real_device_type = "mobile"
 | 
			
		||||
        elif window_width < dp(1100):
 | 
			
		||||
            self.real_device_type = "tablet"
 | 
			
		||||
        else:
 | 
			
		||||
            self.real_device_type = "desktop"
 | 
			
		||||
 | 
			
		||||
    def get_real_device_type(self) -> str:
 | 
			
		||||
        """Returns the device type - 'mobile', 'tablet' or 'desktop'."""
 | 
			
		||||
 | 
			
		||||
        return self.real_device_type
 | 
			
		||||
 | 
			
		||||
    def get_window_width_resizing_direction(self) -> str:
 | 
			
		||||
        """Return window width resizing direction - 'left' or 'right'"""
 | 
			
		||||
        """Return window width resizing direction - 'left' or 'right'."""
 | 
			
		||||
 | 
			
		||||
        return self.window_resizing_direction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
#:import DEVICE_TYPE kivymd.material_resources.DEVICE_TYPE
 | 
			
		||||
#:import FakeRectangularElevationBehavior kivymd.uix.behaviors.FakeRectangularElevationBehavior
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<CellRow>
 | 
			
		||||
@ -66,7 +65,7 @@
 | 
			
		||||
    size_hint_y: None
 | 
			
		||||
    height: self.minimum_height
 | 
			
		||||
    spacing: "4dp"
 | 
			
		||||
    tooltip_text: root.text
 | 
			
		||||
    tooltip_text: root.tooltip if root.tooltip else root.text
 | 
			
		||||
 | 
			
		||||
    BoxLayout:
 | 
			
		||||
        id: box
 | 
			
		||||
@ -175,7 +174,11 @@
 | 
			
		||||
        font_size: "14sp"
 | 
			
		||||
        on_release: root.table_data.open_pagination_menu()
 | 
			
		||||
        text:
 | 
			
		||||
            f"{root.table_data.rows_num if root.table_data.rows_num < len(root.table_data.row_data) else len(root.table_data.row_data)}"
 | 
			
		||||
            "{}".format( \
 | 
			
		||||
            root.table_data.rows_num \
 | 
			
		||||
            if root.table_data.rows_num < len(root.table_data.row_data) else \
 | 
			
		||||
            len(root.table_data.row_data) \
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    Widget:
 | 
			
		||||
        size_hint_x: None
 | 
			
		||||
@ -192,9 +195,11 @@
 | 
			
		||||
            if root.theme_cls.theme_style == "Dark" else \
 | 
			
		||||
            (0, 0, 0, 1)
 | 
			
		||||
        text:
 | 
			
		||||
            f"1-" \
 | 
			
		||||
            f"{root.table_data.rows_num if root.table_data.rows_num > len(root.table_data.row_data) else len(root.table_data.row_data)} " \
 | 
			
		||||
            f"of {len(root.table_data.row_data)}"
 | 
			
		||||
            "1-{} of {}".format( \
 | 
			
		||||
            root.table_data.rows_num \
 | 
			
		||||
            if root.table_data.rows_num > len(root.table_data.row_data) else \
 | 
			
		||||
            len(root.table_data.row_data), len(root.table_data.row_data) \
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    MDIconButton:
 | 
			
		||||
        id: button_back
 | 
			
		||||
@ -217,7 +222,7 @@
 | 
			
		||||
        on_release: root.table_data.set_next_row_data_parts("forward")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<TableContainer@MDCard+FakeRectangularElevationBehavior>
 | 
			
		||||
<TableContainer@MDCard>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDDataTable>
 | 
			
		||||
 | 
			
		||||
@ -11,19 +11,6 @@ Components/DataTables
 | 
			
		||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-previous.png
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
Warnings
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
.. warning:: Data tables are still far from perfect. The class is in constant
 | 
			
		||||
    change, because of optimizations and bug fixes. If you find a bug or have
 | 
			
		||||
    an improvement you want to share, take some time and share your discoveries
 | 
			
		||||
    with us over the main git repo.
 | 
			
		||||
    Any help is well appreciated.
 | 
			
		||||
 | 
			
		||||
.. warning:: In versions prior to `Kivy 2.1.0-dev0` exists an error in which is
 | 
			
		||||
    the table has only one row in the current page, the table will only render
 | 
			
		||||
    one column instead of the whole row.
 | 
			
		||||
 | 
			
		||||
.. note:: `MDDataTable` allows developers to sort the data provided by column.
 | 
			
		||||
    This happens thanks to the use of an external function that you can bind
 | 
			
		||||
    while you're defining the table columns. Be aware that the sorting function
 | 
			
		||||
@ -159,6 +146,15 @@ class CellHeader(MDTooltip, BoxLayout):
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    tooltip = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
    Tooltip containing descriptive text for the column.
 | 
			
		||||
    If the tooltip is not provided, column `text` shall be used instead.
 | 
			
		||||
 | 
			
		||||
    :attr:`tooltip` is a :class:`~kivy.properties.StringProperty`
 | 
			
		||||
    and defaults to `''`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # TODO: Added example.
 | 
			
		||||
    sort_action = ObjectProperty()
 | 
			
		||||
    """
 | 
			
		||||
@ -340,11 +336,19 @@ class TableHeader(ThemableBehavior, ScrollView):
 | 
			
		||||
                        CellHeader(
 | 
			
		||||
                            text=col_heading[0],
 | 
			
		||||
                            sort_action=col_heading[2],
 | 
			
		||||
                            tooltip=col_heading[3],
 | 
			
		||||
                            width=self.cols_minimum[i],
 | 
			
		||||
                            table_data=self.table_data,
 | 
			
		||||
                            is_sorted=(col_heading[0] == self.sorted_on),
 | 
			
		||||
                            sorted_order=self.sorted_order,
 | 
			
		||||
                        )
 | 
			
		||||
                        if len(col_heading) == 4
 | 
			
		||||
                        else CellHeader(
 | 
			
		||||
                            text=col_heading[0],
 | 
			
		||||
                            sort_action=col_heading[2],
 | 
			
		||||
                            width=self.cols_minimum[i],
 | 
			
		||||
                            table_data=self.table_data,
 | 
			
		||||
                        )
 | 
			
		||||
                        if len(col_heading) == 3
 | 
			
		||||
                        else CellHeader(
 | 
			
		||||
                            text=col_heading[0],
 | 
			
		||||
@ -356,6 +360,9 @@ class TableHeader(ThemableBehavior, ScrollView):
 | 
			
		||||
            else:
 | 
			
		||||
                # Sets the text in the first cell.
 | 
			
		||||
                self.ids.first_cell.text = col_heading[0]
 | 
			
		||||
                self.ids.first_cell.tooltip = (
 | 
			
		||||
                    col_heading[3] if len(col_heading) == 4 else ""
 | 
			
		||||
                )
 | 
			
		||||
                self.ids.first_cell.ids.separator.height = 0
 | 
			
		||||
                self.ids.first_cell.width = self.cols_minimum[i]
 | 
			
		||||
 | 
			
		||||
@ -765,6 +772,9 @@ class TablePagination(ThemableBehavior, MDBoxLayout):
 | 
			
		||||
 | 
			
		||||
class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
    """
 | 
			
		||||
    See :class:`~kivy.uix.anchorlayout.AnchorLayout` class documentation for
 | 
			
		||||
    more information.
 | 
			
		||||
 | 
			
		||||
    :Events:
 | 
			
		||||
        :attr:`on_row_press`
 | 
			
		||||
            Called when a table row is clicked.
 | 
			
		||||
@ -775,7 +785,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        from kivy.metrics import dp
 | 
			
		||||
 | 
			
		||||
        from kivymd.app import MDApp
 | 
			
		||||
@ -914,38 +923,82 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Data for header columns.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
    .. tabs::
 | 
			
		||||
 | 
			
		||||
        from kivy.metrics import dp
 | 
			
		||||
        .. tab:: Imperative python style
 | 
			
		||||
 | 
			
		||||
        from kivymd.app import MDApp
 | 
			
		||||
        from kivymd.uix.datatables import MDDataTable
 | 
			
		||||
        from kivy.uix.anchorlayout import AnchorLayout
 | 
			
		||||
            .. code-block:: python
 | 
			
		||||
 | 
			
		||||
                from kivy.metrics import dp
 | 
			
		||||
 | 
			
		||||
                from kivymd.app import MDApp
 | 
			
		||||
                from kivymd.uix.datatables import MDDataTable
 | 
			
		||||
                from kivy.uix.anchorlayout import AnchorLayout
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            def build(self):
 | 
			
		||||
                layout = AnchorLayout()
 | 
			
		||||
                self.data_tables = MDDataTable(
 | 
			
		||||
                    size_hint=(0.7, 0.6),
 | 
			
		||||
                    use_pagination=True,
 | 
			
		||||
                    check=True,
 | 
			
		||||
                    # name column, width column, sorting function column(optional)
 | 
			
		||||
                    column_data=[
 | 
			
		||||
                        ("No.", dp(30)),
 | 
			
		||||
                        ("Status", dp(30)),
 | 
			
		||||
                        ("Signal Name", dp(60)),
 | 
			
		||||
                        ("Severity", dp(30)),
 | 
			
		||||
                        ("Stage", dp(30)),
 | 
			
		||||
                        ("Schedule", dp(30), lambda *args: print("Sorted using Schedule")),
 | 
			
		||||
                        ("Team Lead", dp(30)),
 | 
			
		||||
                    ],
 | 
			
		||||
                )
 | 
			
		||||
                layout.add_widget(self.data_tables)
 | 
			
		||||
                return layout
 | 
			
		||||
                class Example(MDApp):
 | 
			
		||||
                    def build(self):
 | 
			
		||||
                        self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                        self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                        layout = AnchorLayout()
 | 
			
		||||
                        self.data_tables = MDDataTable(
 | 
			
		||||
                            size_hint=(0.7, 0.6),
 | 
			
		||||
                            use_pagination=True,
 | 
			
		||||
                            check=True,
 | 
			
		||||
                            # name column, width column, sorting function column(optional), custom tooltip
 | 
			
		||||
                            column_data=[
 | 
			
		||||
                                ("No.", dp(30), None, "Custom tooltip"),
 | 
			
		||||
                                ("Status", dp(30)),
 | 
			
		||||
                                ("Signal Name", dp(60)),
 | 
			
		||||
                                ("Severity", dp(30)),
 | 
			
		||||
                                ("Stage", dp(30)),
 | 
			
		||||
                                ("Schedule", dp(30), lambda *args: print("Sorted using Schedule")),
 | 
			
		||||
                                ("Team Lead", dp(30)),
 | 
			
		||||
                            ],
 | 
			
		||||
                        )
 | 
			
		||||
                        layout.add_widget(self.data_tables)
 | 
			
		||||
                        return layout
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Example().run()
 | 
			
		||||
                Example().run()
 | 
			
		||||
 | 
			
		||||
        .. tab:: Declarative python style
 | 
			
		||||
 | 
			
		||||
            .. code-block:: python
 | 
			
		||||
 | 
			
		||||
                from kivy.metrics import dp
 | 
			
		||||
 | 
			
		||||
                from kivymd.app import MDApp
 | 
			
		||||
                from kivymd.uix.anchorlayout import MDAnchorLayout
 | 
			
		||||
                from kivymd.uix.datatables import MDDataTable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                class Example(MDApp):
 | 
			
		||||
                    def build(self):
 | 
			
		||||
                        self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                        self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                        return MDAnchorLayout(
 | 
			
		||||
                            MDDataTable(
 | 
			
		||||
                                size_hint=(0.7, 0.6),
 | 
			
		||||
                                use_pagination=True,
 | 
			
		||||
                                check=True,
 | 
			
		||||
                                # name column, width column, sorting function column(optional)
 | 
			
		||||
                                column_data=[
 | 
			
		||||
                                    ("No.", dp(30)),
 | 
			
		||||
                                    ("Status", dp(30)),
 | 
			
		||||
                                    ("Signal Name", dp(60)),
 | 
			
		||||
                                    ("Severity", dp(30)),
 | 
			
		||||
                                    ("Stage", dp(30)),
 | 
			
		||||
                                    ("Schedule", dp(30),
 | 
			
		||||
                                     lambda *args: print("Sorted using Schedule")),
 | 
			
		||||
                                    ("Team Lead", dp(30)),
 | 
			
		||||
                                ],
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                Example().run()
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-column-data.png
 | 
			
		||||
        :align: center
 | 
			
		||||
@ -1060,6 +1113,9 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            def build(self):
 | 
			
		||||
                self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                layout = AnchorLayout()
 | 
			
		||||
                data_tables = MDDataTable(
 | 
			
		||||
                    size_hint=(0.9, 0.6),
 | 
			
		||||
@ -1187,7 +1243,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Use or not use checkboxes for rows.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-check.gif
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-check.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`check` is an :class:`~kivy.properties.BooleanProperty`
 | 
			
		||||
@ -1209,6 +1265,9 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            def build(self):
 | 
			
		||||
                self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                layout = AnchorLayout()
 | 
			
		||||
                data_tables = MDDataTable(
 | 
			
		||||
                    size_hint=(0.9, 0.6),
 | 
			
		||||
@ -1238,19 +1297,19 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
    and defaults to `False`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    elevation = NumericProperty(8)
 | 
			
		||||
    elevation = NumericProperty(4)
 | 
			
		||||
    """
 | 
			
		||||
    Table elevation.
 | 
			
		||||
 | 
			
		||||
    :attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `8`.
 | 
			
		||||
    and defaults to `4`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    rows_num = NumericProperty(5)
 | 
			
		||||
    """
 | 
			
		||||
    The number of rows displayed on one page of the table.
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-use-pagination.gif
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-use-pagination-rows-num.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`rows_num` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
@ -1266,7 +1325,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    .. rubric:: Center
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-pos-center.png
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-pos-top.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    .. rubric:: Auto
 | 
			
		||||
@ -1282,11 +1341,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
    """
 | 
			
		||||
    Menu height for selecting the number of displayed rows.
 | 
			
		||||
 | 
			
		||||
    .. rubric:: 140dp
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-height-140.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    .. rubric:: 240dp
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-height-240.png
 | 
			
		||||
@ -1298,7 +1352,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    background_color = ColorProperty([0, 0, 0, 0])
 | 
			
		||||
    """
 | 
			
		||||
    Background color in the format (r, g, b, a).
 | 
			
		||||
    Background color in the format (r, g, b, a) or string format.
 | 
			
		||||
    See :attr:`~kivy.uix.modalview.ModalView.background_color`.
 | 
			
		||||
 | 
			
		||||
    Use markup strings
 | 
			
		||||
@ -1315,6 +1369,9 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            def build(self):
 | 
			
		||||
                self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                layout = AnchorLayout()
 | 
			
		||||
                data_tables = MDDataTable(
 | 
			
		||||
                    size_hint=(0.9, 0.6),
 | 
			
		||||
@ -1354,7 +1411,8 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    background_color_header = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Background color for :class:`~TableHeader` class.
 | 
			
		||||
    Background color in the format (r, g, b, a) or string format for
 | 
			
		||||
    :class:`~TableHeader` class.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
@ -1374,7 +1432,8 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    background_color_cell = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Background color for :class:`~CellRow` class.
 | 
			
		||||
    Background color in the format (r, g, b, a) or string format for
 | 
			
		||||
    :class:`~CellRow` class.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
@ -1395,7 +1454,8 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
 | 
			
		||||
    background_color_selected_cell = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Background selected color for :class:`~CellRow` class.
 | 
			
		||||
    Background selected color in the format (r, g, b, a) or string format for
 | 
			
		||||
    :class:`~CellRow` class.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.0.0
 | 
			
		||||
 | 
			
		||||
@ -1408,7 +1468,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
            background_color_selected_cell="e4514f",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-background-color-selected-cell.gif
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-background-color-selected-cell.png
 | 
			
		||||
        :align: center
 | 
			
		||||
 | 
			
		||||
    :attr:`background_color_selected_cell` is a :class:`~kivy.properties.ColorProperty` and
 | 
			
		||||
@ -1503,6 +1563,9 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
                data_tables = None
 | 
			
		||||
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                    layout = MDFloatLayout()  # root layout
 | 
			
		||||
                    # Creating control buttons.
 | 
			
		||||
                    button_box = MDBoxLayout(
 | 
			
		||||
@ -1604,6 +1667,9 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
 | 
			
		||||
                data_tables = None
 | 
			
		||||
 | 
			
		||||
                def build(self):
 | 
			
		||||
                    self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                    self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
 | 
			
		||||
                    layout = MDFloatLayout()
 | 
			
		||||
                    layout.add_widget(
 | 
			
		||||
                        MDRaisedButton(
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,11 @@
 | 
			
		||||
        PopMatrix
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<DialogContainer@MDCard+FakeRectangularElevationBehavior>
 | 
			
		||||
<DialogContainer@MDCard>
 | 
			
		||||
    shadow_color: 0.0, 0.0, 0.0, 0.0
 | 
			
		||||
    elevation: 0
 | 
			
		||||
    shadow_softness: 0
 | 
			
		||||
    shadow_offset: 0, 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDDialog>
 | 
			
		||||
@ -28,7 +32,6 @@
 | 
			
		||||
        orientation: "vertical"
 | 
			
		||||
        size_hint_y: None
 | 
			
		||||
        height: self.minimum_height
 | 
			
		||||
        elevation: 24
 | 
			
		||||
        padding: "24dp", "24dp", "8dp", "8dp"
 | 
			
		||||
        radius: root.radius
 | 
			
		||||
        md_bg_color:
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,8 @@ Usage
 | 
			
		||||
        dialog = None
 | 
			
		||||
 | 
			
		||||
        def build(self):
 | 
			
		||||
            self.theme_cls.theme_style = "Dark"
 | 
			
		||||
            self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
        def show_alert_dialog(self):
 | 
			
		||||
@ -87,6 +89,7 @@ from kivy.uix.modalview import ModalView
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.material_resources import DEVICE_TYPE
 | 
			
		||||
from kivymd.theming import ThemableBehavior
 | 
			
		||||
from kivymd.uix.behaviors import CommonElevationBehavior
 | 
			
		||||
from kivymd.uix.button import BaseButton
 | 
			
		||||
from kivymd.uix.card import MDSeparator
 | 
			
		||||
from kivymd.uix.list import BaseListItem
 | 
			
		||||
@ -97,7 +100,40 @@ with open(
 | 
			
		||||
    Builder.load_string(kv_file.read())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseDialog(ThemableBehavior, ModalView):
 | 
			
		||||
class BaseDialog(ThemableBehavior, ModalView, CommonElevationBehavior):
 | 
			
		||||
    elevation = NumericProperty(3)
 | 
			
		||||
    """
 | 
			
		||||
    See :attr:`kivymd.uix.behaviors.elevation.CommonElevationBehavior.elevation`
 | 
			
		||||
    attribute for more information.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `3`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    shadow_softness = NumericProperty(24)
 | 
			
		||||
    """
 | 
			
		||||
    See :attr:`kivymd.uix.behaviors.elevation.CommonElevationBehavior.shadow_softness`
 | 
			
		||||
    attribute for more information.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`shadow_softness` is an :class:`~kivy.properties.NumericProperty`
 | 
			
		||||
    and defaults to `24`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    shadow_offset = ListProperty((0, 4))
 | 
			
		||||
    """
 | 
			
		||||
    See :attr:`kivymd.uix.behaviors.elevation.CommonElevationBehavior.shadow_offset`
 | 
			
		||||
    attribute for more information.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 1.1.0
 | 
			
		||||
 | 
			
		||||
    :attr:`shadow_offset` is an :class:`~kivy.properties.ListProperty`
 | 
			
		||||
    and defaults to `[0, 4]`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    radius = ListProperty([dp(7), dp(7), dp(7), dp(7)])
 | 
			
		||||
    """
 | 
			
		||||
    Dialog corners rounding value.
 | 
			
		||||
@ -250,21 +286,22 @@ class MDDialog(BaseDialog):
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            dialog = None
 | 
			
		||||
 | 
			
		||||
            def build(self):
 | 
			
		||||
                return Builder.load_string(KV)
 | 
			
		||||
        def build(self):
 | 
			
		||||
            self.theme_cls.theme_style = "Dark"
 | 
			
		||||
            self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
            return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
            def show_simple_dialog(self):
 | 
			
		||||
                if not self.dialog:
 | 
			
		||||
                    self.dialog = MDDialog(
 | 
			
		||||
                        title="Set backup account",
 | 
			
		||||
                        type="simple",
 | 
			
		||||
                        items=[
 | 
			
		||||
                            Item(text="user01@gmail.com", source="user-1.png"),
 | 
			
		||||
                            Item(text="user02@gmail.com", source="user-2.png"),
 | 
			
		||||
                            Item(text="Add account", source="add-icon.png"),
 | 
			
		||||
                        ],
 | 
			
		||||
                    )
 | 
			
		||||
                self.dialog.open()
 | 
			
		||||
        def show_simple_dialog(self):
 | 
			
		||||
            if not self.dialog:
 | 
			
		||||
                self.dialog = MDDialog(
 | 
			
		||||
                    title="Set backup account",
 | 
			
		||||
                    type="simple",
 | 
			
		||||
                    items=[
 | 
			
		||||
                        Item(text="user01@gmail.com", source="kivymd/images/logo/kivymd-icon-128.png"),
 | 
			
		||||
                        Item(text="user02@gmail.com", source="data/logo/kivy-icon-128.png"),
 | 
			
		||||
                    ],
 | 
			
		||||
                )
 | 
			
		||||
            self.dialog.open()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Example().run()
 | 
			
		||||
@ -317,6 +354,8 @@ class MDDialog(BaseDialog):
 | 
			
		||||
            dialog = None
 | 
			
		||||
 | 
			
		||||
            def build(self):
 | 
			
		||||
                self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
            def show_confirmation_dialog(self):
 | 
			
		||||
@ -385,71 +424,140 @@ class MDDialog(BaseDialog):
 | 
			
		||||
    """
 | 
			
		||||
    Custom content class.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
    .. tabs::
 | 
			
		||||
 | 
			
		||||
        from kivy.lang import Builder
 | 
			
		||||
        from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
        .. tab:: Declarative KV style
 | 
			
		||||
 | 
			
		||||
        from kivymd.app import MDApp
 | 
			
		||||
        from kivymd.uix.button import MDFlatButton
 | 
			
		||||
        from kivymd.uix.dialog import MDDialog
 | 
			
		||||
            .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        KV = '''
 | 
			
		||||
        <Content>
 | 
			
		||||
            orientation: "vertical"
 | 
			
		||||
            spacing: "12dp"
 | 
			
		||||
            size_hint_y: None
 | 
			
		||||
            height: "120dp"
 | 
			
		||||
                from kivy.lang import Builder
 | 
			
		||||
                from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
 | 
			
		||||
            MDTextField:
 | 
			
		||||
                hint_text: "City"
 | 
			
		||||
                from kivymd.app import MDApp
 | 
			
		||||
                from kivymd.uix.button import MDFlatButton
 | 
			
		||||
                from kivymd.uix.dialog import MDDialog
 | 
			
		||||
 | 
			
		||||
            MDTextField:
 | 
			
		||||
                hint_text: "Street"
 | 
			
		||||
                KV = '''
 | 
			
		||||
                <Content>
 | 
			
		||||
                    orientation: "vertical"
 | 
			
		||||
                    spacing: "12dp"
 | 
			
		||||
                    size_hint_y: None
 | 
			
		||||
                    height: "120dp"
 | 
			
		||||
 | 
			
		||||
                    MDTextField:
 | 
			
		||||
                        hint_text: "City"
 | 
			
		||||
 | 
			
		||||
                    MDTextField:
 | 
			
		||||
                        hint_text: "Street"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        MDFloatLayout:
 | 
			
		||||
                MDFloatLayout:
 | 
			
		||||
 | 
			
		||||
            MDFlatButton:
 | 
			
		||||
                text: "ALERT DIALOG"
 | 
			
		||||
                pos_hint: {'center_x': .5, 'center_y': .5}
 | 
			
		||||
                on_release: app.show_confirmation_dialog()
 | 
			
		||||
        '''
 | 
			
		||||
                    MDFlatButton:
 | 
			
		||||
                        text: "ALERT DIALOG"
 | 
			
		||||
                        pos_hint: {'center_x': .5, 'center_y': .5}
 | 
			
		||||
                        on_release: app.show_confirmation_dialog()
 | 
			
		||||
                '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        class Content(BoxLayout):
 | 
			
		||||
            pass
 | 
			
		||||
                class Content(BoxLayout):
 | 
			
		||||
                    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        class Example(MDApp):
 | 
			
		||||
            dialog = None
 | 
			
		||||
                class Example(MDApp):
 | 
			
		||||
                    dialog = None
 | 
			
		||||
 | 
			
		||||
            def build(self):
 | 
			
		||||
                return Builder.load_string(KV)
 | 
			
		||||
                    def build(self):
 | 
			
		||||
                        self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                        self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                        return Builder.load_string(KV)
 | 
			
		||||
 | 
			
		||||
            def show_confirmation_dialog(self):
 | 
			
		||||
                if not self.dialog:
 | 
			
		||||
                    self.dialog = MDDialog(
 | 
			
		||||
                        title="Address:",
 | 
			
		||||
                        type="custom",
 | 
			
		||||
                        content_cls=Content(),
 | 
			
		||||
                        buttons=[
 | 
			
		||||
                            MDFlatButton(
 | 
			
		||||
                                text="CANCEL",
 | 
			
		||||
                                theme_text_color="Custom",
 | 
			
		||||
                                text_color=self.theme_cls.primary_color,
 | 
			
		||||
                            ),
 | 
			
		||||
                            MDFlatButton(
 | 
			
		||||
                                text="OK",
 | 
			
		||||
                                theme_text_color="Custom",
 | 
			
		||||
                                text_color=self.theme_cls.primary_color,
 | 
			
		||||
                            ),
 | 
			
		||||
                        ],
 | 
			
		||||
                    )
 | 
			
		||||
                self.dialog.open()
 | 
			
		||||
                    def show_confirmation_dialog(self):
 | 
			
		||||
                        if not self.dialog:
 | 
			
		||||
                            self.dialog = MDDialog(
 | 
			
		||||
                                title="Address:",
 | 
			
		||||
                                type="custom",
 | 
			
		||||
                                content_cls=Content(),
 | 
			
		||||
                                buttons=[
 | 
			
		||||
                                    MDFlatButton(
 | 
			
		||||
                                        text="CANCEL",
 | 
			
		||||
                                        theme_text_color="Custom",
 | 
			
		||||
                                        text_color=self.theme_cls.primary_color,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    MDFlatButton(
 | 
			
		||||
                                        text="OK",
 | 
			
		||||
                                        theme_text_color="Custom",
 | 
			
		||||
                                        text_color=self.theme_cls.primary_color,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                ],
 | 
			
		||||
                            )
 | 
			
		||||
                        self.dialog.open()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Example().run()
 | 
			
		||||
                Example().run()
 | 
			
		||||
 | 
			
		||||
        .. tab:: Declarative Python style
 | 
			
		||||
 | 
			
		||||
            .. code-block:: python
 | 
			
		||||
 | 
			
		||||
                from kivymd.app import MDApp
 | 
			
		||||
                from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
                from kivymd.uix.button import MDFlatButton
 | 
			
		||||
                from kivymd.uix.dialog import MDDialog
 | 
			
		||||
                from kivymd.uix.floatlayout import MDFloatLayout
 | 
			
		||||
                from kivymd.uix.textfield import MDTextField
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                class Example(MDApp):
 | 
			
		||||
                    dialog = None
 | 
			
		||||
 | 
			
		||||
                    def build(self):
 | 
			
		||||
                        self.theme_cls.theme_style = "Dark"
 | 
			
		||||
                        self.theme_cls.primary_palette = "Orange"
 | 
			
		||||
                        return (
 | 
			
		||||
                            MDFloatLayout(
 | 
			
		||||
                                MDFlatButton(
 | 
			
		||||
                                    text="ALERT DIALOG",
 | 
			
		||||
                                    pos_hint={'center_x': 0.5, 'center_y': 0.5},
 | 
			
		||||
                                    on_release=self.show_confirmation_dialog,
 | 
			
		||||
                                )
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
 | 
			
		||||
                    def show_confirmation_dialog(self, *args):
 | 
			
		||||
                        if not self.dialog:
 | 
			
		||||
                            self.dialog = MDDialog(
 | 
			
		||||
                                title="Address:",
 | 
			
		||||
                                type="custom",
 | 
			
		||||
                                content_cls=MDBoxLayout(
 | 
			
		||||
                                    MDTextField(
 | 
			
		||||
                                        hint_text="City",
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    MDTextField(
 | 
			
		||||
                                        hint_text="Street",
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    orientation="vertical",
 | 
			
		||||
                                    spacing="12dp",
 | 
			
		||||
                                    size_hint_y=None,
 | 
			
		||||
                                    height="120dp",
 | 
			
		||||
                                ),
 | 
			
		||||
                                buttons=[
 | 
			
		||||
                                    MDFlatButton(
 | 
			
		||||
                                        text="CANCEL",
 | 
			
		||||
                                        theme_text_color="Custom",
 | 
			
		||||
                                        text_color=self.theme_cls.primary_color,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    MDFlatButton(
 | 
			
		||||
                                        text="OK",
 | 
			
		||||
                                        theme_text_color="Custom",
 | 
			
		||||
                                        text_color=self.theme_cls.primary_color,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                ],
 | 
			
		||||
                            )
 | 
			
		||||
                        self.dialog.open()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                Example().run()
 | 
			
		||||
 | 
			
		||||
    .. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-custom.png
 | 
			
		||||
        :align: center
 | 
			
		||||
@ -460,7 +568,7 @@ class MDDialog(BaseDialog):
 | 
			
		||||
 | 
			
		||||
    md_bg_color = ColorProperty(None)
 | 
			
		||||
    """
 | 
			
		||||
    Background color in the format (r, g, b, a).
 | 
			
		||||
    Background color in the (r, g, b, a) or string format.
 | 
			
		||||
 | 
			
		||||
    :attr:`md_bg_color` is an :class:`~kivy.properties.ColorProperty`
 | 
			
		||||
    and defaults to `None`.
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<_Triangle>:
 | 
			
		||||
    canvas:
 | 
			
		||||
        Color:
 | 
			
		||||
            rgba: root.theme_cls.text_color
 | 
			
		||||
            rgba: app.theme_cls.text_color
 | 
			
		||||
        Triangle:
 | 
			
		||||
            points:
 | 
			
		||||
                [ \
 | 
			
		||||
@ -13,7 +13,8 @@
 | 
			
		||||
 | 
			
		||||
<MDDropDownItem>
 | 
			
		||||
    orientation: "vertical"
 | 
			
		||||
    adaptive_size: True
 | 
			
		||||
    size_hint: None, None
 | 
			
		||||
    size: self.minimum_size
 | 
			
		||||
    spacing: "5dp"
 | 
			
		||||
    padding: "5dp", "5dp", "5dp", 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,13 +15,13 @@ Usage
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
 | 
			
		||||
    KV = '''
 | 
			
		||||
    Screen
 | 
			
		||||
    MDScreen
 | 
			
		||||
 | 
			
		||||
        MDDropDownItem:
 | 
			
		||||
            id: drop_item
 | 
			
		||||
            pos_hint: {'center_x': .5, 'center_y': .5}
 | 
			
		||||
            text: 'Item'
 | 
			
		||||
            on_release: self.set_item("New Item")
 | 
			
		||||
            on_release: print("Press item")
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -48,12 +48,12 @@ import os
 | 
			
		||||
from kivy.lang import Builder
 | 
			
		||||
from kivy.properties import NumericProperty, StringProperty
 | 
			
		||||
from kivy.uix.behaviors import ButtonBehavior
 | 
			
		||||
from kivy.uix.boxlayout import BoxLayout
 | 
			
		||||
from kivy.uix.widget import Widget
 | 
			
		||||
 | 
			
		||||
from kivymd import uix_path
 | 
			
		||||
from kivymd.theming import ThemableBehavior
 | 
			
		||||
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
 | 
			
		||||
from kivymd.uix.boxlayout import MDBoxLayout
 | 
			
		||||
from kivymd.uix.behaviors import DeclarativeBehavior
 | 
			
		||||
 | 
			
		||||
with open(
 | 
			
		||||
    os.path.join(uix_path, "dropdownitem", "dropdownitem.kv"), encoding="utf-8"
 | 
			
		||||
@ -61,15 +61,12 @@ with open(
 | 
			
		||||
    Builder.load_string(kv_file.read())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _Triangle(ThemableBehavior, Widget):
 | 
			
		||||
class _Triangle(Widget):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MDDropDownItem(
 | 
			
		||||
    ThemableBehavior,
 | 
			
		||||
    FakeRectangularElevationBehavior,
 | 
			
		||||
    ButtonBehavior,
 | 
			
		||||
    MDBoxLayout,
 | 
			
		||||
    DeclarativeBehavior, ThemableBehavior, ButtonBehavior, BoxLayout
 | 
			
		||||
):
 | 
			
		||||
    text = StringProperty()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,8 @@ Example
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    import os
 | 
			
		||||
 | 
			
		||||
    from kivy.lang import Builder
 | 
			
		||||
 | 
			
		||||
    from kivymd.app import MDApp
 | 
			
		||||
@ -75,7 +77,7 @@ Example
 | 
			
		||||
                icon: 'phone'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ScrollView:
 | 
			
		||||
    MDScrollView:
 | 
			
		||||
 | 
			
		||||
        MDGridLayout:
 | 
			
		||||
            id: box
 | 
			
		||||
@ -96,7 +98,7 @@ Example
 | 
			
		||||
            for i in range(10):
 | 
			
		||||
                self.root.ids.box.add_widget(
 | 
			
		||||
                    MDExpansionPanel(
 | 
			
		||||
                        icon=f"{images_path}kivymd.png",
 | 
			
		||||
                        icon=os.path.join(images_path, "logo", "kivymd-icon-128.png"),
 | 
			
		||||
                        content=Content(),
 | 
			
		||||
                        panel_cls=MDExpansionPanelThreeLine(
 | 
			
		||||
                            text="Text",
 | 
			
		||||
 | 
			
		||||
@ -6,28 +6,29 @@
 | 
			
		||||
    background_normal: ""
 | 
			
		||||
    background_down: ""
 | 
			
		||||
    dir_or_file_name: ""
 | 
			
		||||
    icon_color: 0, 0, 0, 0
 | 
			
		||||
    _selected: False
 | 
			
		||||
    events_callback: lambda x: None
 | 
			
		||||
    orientation: "vertical"
 | 
			
		||||
 | 
			
		||||
    ModifiedOneLineIconListItem:
 | 
			
		||||
        text: root.dir_or_file_name
 | 
			
		||||
        on_release: root.events_callback(root.path, root)
 | 
			
		||||
        bg_color:
 | 
			
		||||
            self.theme_cls.bg_darkest \
 | 
			
		||||
            if root._selected else self.theme_cls.bg_normal
 | 
			
		||||
        on_release: root.events_callback(root.path, root)
 | 
			
		||||
            if root._selected else \
 | 
			
		||||
            self.theme_cls.bg_normal
 | 
			
		||||
 | 
			
		||||
        IconLeftWidget:
 | 
			
		||||
            icon: root.icon
 | 
			
		||||
            theme_text_color: "Custom"
 | 
			
		||||
            text_color: self.theme_cls.primary_color
 | 
			
		||||
            theme_icon_color: "Custom"
 | 
			
		||||
            icon_color: root.icon_color
 | 
			
		||||
 | 
			
		||||
    MDSeparator:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<LabelContent@MDLabel>
 | 
			
		||||
    size_hint_y: None
 | 
			
		||||
    height: self.texture_size[1]
 | 
			
		||||
    adaptive_height: True
 | 
			
		||||
    shorten: True
 | 
			
		||||
    shorten_from: "center"
 | 
			
		||||
    halign: "center"
 | 
			
		||||
@ -61,23 +62,6 @@
 | 
			
		||||
        text: root.name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<FloatButton>
 | 
			
		||||
    anchor_x: "right"
 | 
			
		||||
    anchor_y: "bottom"
 | 
			
		||||
    size_hint_y: None
 | 
			
		||||
    height: dp(56)
 | 
			
		||||
    padding: dp(10)
 | 
			
		||||
 | 
			
		||||
    MDFloatingActionButton:
 | 
			
		||||
        size_hint: None, None
 | 
			
		||||
        size:dp(56), dp(56)
 | 
			
		||||
        icon: root.icon
 | 
			
		||||
        opposite_colors: True
 | 
			
		||||
        elevation: 8
 | 
			
		||||
        on_release: root.callback()
 | 
			
		||||
        md_bg_color: root.md_bg_color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<MDFileManager>
 | 
			
		||||
    md_bg_color: root.theme_cls.bg_normal
 | 
			
		||||
 | 
			
		||||
@ -90,7 +74,11 @@
 | 
			
		||||
            title: root.current_path
 | 
			
		||||
            right_action_items: [["close-box", lambda x: root.exit_manager(1)]]
 | 
			
		||||
            left_action_items: [["chevron-left", lambda x: root.back()]]
 | 
			
		||||
            elevation: 10
 | 
			
		||||
            elevation: 3
 | 
			
		||||
            md_bg_color:
 | 
			
		||||
                app.theme_cls.primary_color \
 | 
			
		||||
                if not root.background_color_toolbar else \
 | 
			
		||||
                root.background_color_toolbar
 | 
			
		||||
 | 
			
		||||
        RecycleView:
 | 
			
		||||
            id: rv
 | 
			
		||||
 | 
			
		||||