Reverted kivymd to avoid shader crash on Android
|
@ -49,9 +49,6 @@ images_path = os.path.join(path, f"images{os.sep}")
|
||||||
uix_path = os.path.join(path, "uix")
|
uix_path = os.path.join(path, "uix")
|
||||||
"""Path to uix directory."""
|
"""Path to uix directory."""
|
||||||
|
|
||||||
glsl_path = os.path.join(path, "data", "glsl")
|
|
||||||
"""Path to glsl directory."""
|
|
||||||
|
|
||||||
_log_message = (
|
_log_message = (
|
||||||
"KivyMD:"
|
"KivyMD:"
|
||||||
+ (" Release" if release else "")
|
+ (" Release" if release else "")
|
||||||
|
|
|
@ -45,7 +45,7 @@ import os
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.logger import Logger
|
from kivy.logger import Logger
|
||||||
from kivy.properties import ObjectProperty, StringProperty
|
from kivy.properties import ObjectProperty
|
||||||
|
|
||||||
from kivymd.theming import ThemeManager
|
from kivymd.theming import ThemeManager
|
||||||
|
|
||||||
|
@ -71,16 +71,6 @@ class MDApp(App, FpsMonitoring):
|
||||||
information.
|
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()
|
theme_cls = ObjectProperty()
|
||||||
"""
|
"""
|
||||||
Instance of :class:`~ThemeManager` class.
|
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()
|
self.screen = Factory.Root()
|
||||||
|
|
||||||
for name_tab in colors.keys():
|
for name_tab in colors.keys():
|
||||||
tab = Tab(title=name_tab)
|
tab = Tab(text=name_tab)
|
||||||
self.screen.ids.android_tabs.add_widget(tab)
|
self.screen.ids.android_tabs.add_widget(tab)
|
||||||
return self.screen
|
return self.screen
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ To demonstrate the shades of the palette, you can run the following code:
|
||||||
{
|
{
|
||||||
"viewclass": "ItemColor",
|
"viewclass": "ItemColor",
|
||||||
"md_bg_color": colors[tab_text][value_color],
|
"md_bg_color": colors[tab_text][value_color],
|
||||||
"title": value_color,
|
"text": value_color,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
#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;
|
|
|
@ -1,10 +0,0 @@
|
||||||
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));
|
|
||||||
}
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 21 KiB |
|
@ -0,0 +1 @@
|
||||||
|
{"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]}}
|
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 43 KiB |
|
@ -0,0 +1 @@
|
||||||
|
{"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]}}
|
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 28 KiB |
|
@ -0,0 +1 @@
|
||||||
|
{"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]}}
|
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 26 KiB |
|
@ -0,0 +1 @@
|
||||||
|
{"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]}}
|
|
@ -35,15 +35,8 @@ assert "Icons" in LabelBase._fonts.keys() # NOQA
|
||||||
|
|
||||||
images = os.listdir(kivymd.images_path)
|
images = os.listdir(kivymd.images_path)
|
||||||
print(images)
|
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 "folder.png" in images
|
||||||
assert "transparent.png" in images
|
assert "rec_shadow.atlas" in images
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
pyi_main.run(
|
pyi_main.run(
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
def test_create_project():
|
def test_create_project():
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
f"python3.10 -m kivymd.tools.patterns.create_project "
|
f"{sys.executable} -m kivymd.tools.patterns.create_project "
|
||||||
f"MVC "
|
f"MVC "
|
||||||
f"{os.path.expanduser('~')} "
|
f"{os.path.expanduser('~')} "
|
||||||
f"TestProject "
|
f"TestProject "
|
||||||
f"python3.10 "
|
f"{sys.executable} "
|
||||||
f"stable "
|
f"master "
|
||||||
f"--name_screen TestProjectScreen "
|
f"--name_screen TestProjectScreen "
|
||||||
f"--name_database restdb "
|
f"--name_database restdb "
|
||||||
f"--use_hotreload yes"
|
f"--use_hotreload yes"
|
||||||
|
|
|
@ -212,8 +212,9 @@ respects, the theming stays as documented.
|
||||||
dictionary :attr:`kivymd.color_definition.colors`.
|
dictionary :attr:`kivymd.color_definition.colors`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from kivy.animation import Animation
|
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
|
from kivy.atlas import Atlas
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.event import EventDispatcher
|
from kivy.event import EventDispatcher
|
||||||
|
@ -223,13 +224,13 @@ from kivy.properties import (
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
DictProperty,
|
DictProperty,
|
||||||
NumericProperty,
|
|
||||||
ObjectProperty,
|
ObjectProperty,
|
||||||
OptionProperty,
|
OptionProperty,
|
||||||
StringProperty,
|
StringProperty,
|
||||||
)
|
)
|
||||||
from kivy.utils import get_color_from_hex
|
from kivy.utils import get_color_from_hex
|
||||||
|
|
||||||
|
from kivymd import images_path
|
||||||
from kivymd.color_definitions import colors, hue, palette
|
from kivymd.color_definitions import colors, hue, palette
|
||||||
from kivymd.font_definitions import theme_font_styles
|
from kivymd.font_definitions import theme_font_styles
|
||||||
from kivymd.material_resources import DEVICE_IOS, DEVICE_TYPE
|
from kivymd.material_resources import DEVICE_IOS, DEVICE_TYPE
|
||||||
|
@ -623,152 +624,6 @@ class ThemeManager(EventDispatcher):
|
||||||
and defaults to `'M2'`.
|
and defaults to `'M2'`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
theme_style_switch_animation = BooleanProperty(False)
|
|
||||||
"""
|
|
||||||
Animate app colors when switching app color scheme ('Dark/light').
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. tabs::
|
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivy.lang import Builder
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
KV = '''
|
|
||||||
MDScreen:
|
|
||||||
|
|
||||||
MDCard:
|
|
||||||
orientation: "vertical"
|
|
||||||
padding: 0, 0, 0 , "36dp"
|
|
||||||
size_hint: .5, .5
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
elevation: 4
|
|
||||||
shadow_radius: 6
|
|
||||||
shadow_offset: 0, 2
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "Theme style - {}".format(app.theme_cls.theme_style)
|
|
||||||
halign: "center"
|
|
||||||
valign: "center"
|
|
||||||
bold: True
|
|
||||||
font_style: "H5"
|
|
||||||
|
|
||||||
MDRaisedButton:
|
|
||||||
text: "Set theme"
|
|
||||||
on_release: app.switch_theme_style()
|
|
||||||
pos_hint: {"center_x": .5}
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style_switch_animation = True
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def switch_theme_style(self):
|
|
||||||
self.theme_cls.primary_palette = (
|
|
||||||
"Orange" if self.theme_cls.primary_palette == "Red" else "Red"
|
|
||||||
)
|
|
||||||
self.theme_cls.theme_style = (
|
|
||||||
"Dark" if self.theme_cls.theme_style == "Light" else "Light"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.button import MDRaisedButton
|
|
||||||
from kivymd.uix.card import MDCard
|
|
||||||
from kivymd.uix.label import MDLabel
|
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style_switch_animation = True
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return (
|
|
||||||
MDScreen(
|
|
||||||
MDCard(
|
|
||||||
MDLabel(
|
|
||||||
id="label",
|
|
||||||
text="Theme style - {}".format(self.theme_cls.theme_style),
|
|
||||||
halign="center",
|
|
||||||
valign="center",
|
|
||||||
bold=True,
|
|
||||||
font_style="H5",
|
|
||||||
),
|
|
||||||
MDRaisedButton(
|
|
||||||
text="Set theme",
|
|
||||||
on_release=self.switch_theme_style,
|
|
||||||
pos_hint={"center_x": 0.5},
|
|
||||||
),
|
|
||||||
id="card",
|
|
||||||
orientation="vertical",
|
|
||||||
padding=(0, 0, 0, "36dp"),
|
|
||||||
size_hint=(0.5, 0.5),
|
|
||||||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
|
||||||
elevation=4,
|
|
||||||
shadow_radius=6,
|
|
||||||
shadow_offset=(0, 2),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def switch_theme_style(self, *args):
|
|
||||||
self.theme_cls.primary_palette = (
|
|
||||||
"Orange" if self.theme_cls.primary_palette == "Red" else "Red"
|
|
||||||
)
|
|
||||||
self.theme_cls.theme_style = (
|
|
||||||
"Dark" if self.theme_cls.theme_style == "Light" else "Light"
|
|
||||||
)
|
|
||||||
self.root.ids.card.ids.label.text = (
|
|
||||||
"Theme style - {}".format(self.theme_cls.theme_style)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/theme-style-switch-animation.gif
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`theme_style_switch_animation` is an :class:`~kivy.properties.BooleanProperty`
|
|
||||||
and defaults to `False`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
theme_style_switch_animation_duration = NumericProperty(0.2)
|
|
||||||
"""
|
|
||||||
Duration of the animation of switching the color scheme of the application
|
|
||||||
("Dark/light").
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
class Example(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style_switch_animation = True
|
|
||||||
self.theme_cls.theme_style_switch_animation_duration = 0.8
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/theme-style-switch-animation-duration.gif
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`theme_style_switch_animation_duration` is an :class:`~kivy.properties.NumericProperty`
|
|
||||||
and defaults to `0.2`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
theme_style = OptionProperty("Light", options=["Light", "Dark"])
|
theme_style = OptionProperty("Light", options=["Light", "Dark"])
|
||||||
"""
|
"""
|
||||||
App theme style.
|
App theme style.
|
||||||
|
@ -1329,22 +1184,14 @@ class ThemeManager(EventDispatcher):
|
||||||
):
|
):
|
||||||
self.set_clearcolor_by_theme_style(theme_style)
|
self.set_clearcolor_by_theme_style(theme_style)
|
||||||
|
|
||||||
_set_clearcolor = False
|
set_clearcolor = BooleanProperty(True)
|
||||||
|
|
||||||
def set_clearcolor_by_theme_style(self, theme_style):
|
def set_clearcolor_by_theme_style(self, theme_style):
|
||||||
if self.theme_style_switch_animation and self._set_clearcolor:
|
if not self.set_clearcolor:
|
||||||
Animation(
|
return
|
||||||
clearcolor=get_color_from_hex(
|
Window.clearcolor = get_color_from_hex(
|
||||||
self.colors[theme_style]["Background"]
|
self.colors[theme_style]["Background"]
|
||||||
),
|
)
|
||||||
d=self.theme_style_switch_animation_duration,
|
|
||||||
t="linear",
|
|
||||||
).start(Window)
|
|
||||||
else:
|
|
||||||
Window.clearcolor = get_color_from_hex(
|
|
||||||
self.colors[theme_style]["Background"]
|
|
||||||
)
|
|
||||||
self._set_clearcolor = True
|
|
||||||
|
|
||||||
# Font name, size (sp), always caps, letter spacing (sp).
|
# Font name, size (sp), always caps, letter spacing (sp).
|
||||||
font_styles = DictProperty(
|
font_styles = DictProperty(
|
||||||
|
@ -1551,6 +1398,10 @@ class ThemeManager(EventDispatcher):
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
self.rec_shadow = Atlas(f"{images_path}rec_shadow.atlas")
|
||||||
|
self.rec_st_shadow = Atlas(f"{images_path}rec_st_shadow.atlas")
|
||||||
|
self.quad_shadow = Atlas(f"{images_path}quad_shadow.atlas")
|
||||||
|
self.round_shadow = Atlas(f"{images_path}round_shadow.atlas")
|
||||||
Clock.schedule_once(lambda x: self.on_theme_style(0, self.theme_style))
|
Clock.schedule_once(lambda x: self.on_theme_style(0, self.theme_style))
|
||||||
self._determine_device_orientation(None, Window.size)
|
self._determine_device_orientation(None, Window.size)
|
||||||
Window.bind(size=self._determine_device_orientation)
|
Window.bind(size=self._determine_device_orientation)
|
||||||
|
@ -1636,16 +1487,6 @@ class ThemableBehavior(EventDispatcher):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.unbind_properties = [
|
|
||||||
"theme_style",
|
|
||||||
"material_style",
|
|
||||||
"device_orientation",
|
|
||||||
"primary_color",
|
|
||||||
"primary_palette",
|
|
||||||
"accent_palette",
|
|
||||||
"text_color",
|
|
||||||
]
|
|
||||||
|
|
||||||
if self.theme_cls is not None:
|
if self.theme_cls is not None:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -1666,24 +1507,3 @@ class ThemableBehavior(EventDispatcher):
|
||||||
)
|
)
|
||||||
self.theme_cls = App.get_running_app().theme_cls
|
self.theme_cls = App.get_running_app().theme_cls
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
# def dec_disabled(self, *args, **kwargs) -> None:
|
|
||||||
# callabacks = self.theme_cls.get_property_observers("theme_style")
|
|
||||||
|
|
||||||
# for callaback in callabacks:
|
|
||||||
# try:
|
|
||||||
# if hasattr(callaback, "proxy") and hasattr(
|
|
||||||
# callaback.proxy, "theme_cls"
|
|
||||||
# ):
|
|
||||||
# for property_name in self.unbind_properties:
|
|
||||||
# self.theme_cls.unbind(
|
|
||||||
# **{
|
|
||||||
# property_name: getattr(
|
|
||||||
# callaback.proxy, callaback.method_name
|
|
||||||
# )
|
|
||||||
# }
|
|
||||||
# )
|
|
||||||
# except ReferenceError:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# super().dec_disabled(*args, **kwargs)
|
|
||||||
|
|
|
@ -13,18 +13,6 @@ from pathlib import Path
|
||||||
import kivymd
|
import kivymd
|
||||||
|
|
||||||
datas = [
|
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.
|
# Add `.ttf` files from the `kivymd/fonts` directory.
|
||||||
(
|
(
|
||||||
kivymd.fonts_path,
|
kivymd.fonts_path,
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
if not root.front_layer_color \
|
if not root.front_layer_color \
|
||||||
else root.front_layer_color
|
else root.front_layer_color
|
||||||
radius:
|
radius:
|
||||||
[root.radius_left, root.radius_right,
|
[root.radius_left, root.radius_left,
|
||||||
0, 0]
|
root.radius_right, root.radius_right]
|
||||||
|
|
||||||
OneLineListItem:
|
OneLineListItem:
|
||||||
id: header_button
|
id: header_button
|
||||||
|
|
|
@ -202,6 +202,7 @@ from kivy.uix.boxlayout import BoxLayout
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
from kivymd.uix.floatlayout import MDFloatLayout
|
from kivymd.uix.floatlayout import MDFloatLayout
|
||||||
|
@ -527,5 +528,5 @@ class _BackLayer(BoxLayout):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class _FrontLayer(MDCard):
|
class _FrontLayer(MDCard, FakeRectangularElevationBehavior):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -35,7 +35,7 @@ Usage
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
id: toolbar
|
id: toolbar
|
||||||
title: "Example Banners"
|
title: "Example Banners"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
pos_hint: {'top': 1}
|
pos_hint: {'top': 1}
|
||||||
|
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
|
@ -157,6 +157,7 @@ from kivy.properties import (
|
||||||
from kivy.uix.widget import Widget
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.button import MDFlatButton
|
from kivymd.uix.button import MDFlatButton
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
@ -176,7 +177,7 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class MDBanner(MDCard):
|
class MDBanner(MDCard, FakeRectangularElevationBehavior):
|
||||||
vertical_pad = NumericProperty(dp(68))
|
vertical_pad = NumericProperty(dp(68))
|
||||||
"""
|
"""
|
||||||
Indent the banner at the top of the screen.
|
Indent the banner at the top of the screen.
|
||||||
|
|
|
@ -11,20 +11,18 @@ from .backgroundcolor_behavior import (
|
||||||
)
|
)
|
||||||
|
|
||||||
# flake8: NOQA
|
# flake8: NOQA
|
||||||
from .declarative_behavior import DeclarativeBehavior
|
from .declarative_bahavior import DeclarativeBehavior
|
||||||
from .elevation import (
|
from .elevation import (
|
||||||
CircularElevationBehavior,
|
CircularElevationBehavior,
|
||||||
CommonElevationBehavior,
|
CommonElevationBehavior,
|
||||||
FakeCircularElevationBehavior,
|
FakeCircularElevationBehavior,
|
||||||
FakeRectangularElevationBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
|
ObservableShadow,
|
||||||
RectangularElevationBehavior,
|
RectangularElevationBehavior,
|
||||||
RoundedRectangularElevationBehavior,
|
RoundedRectangularElevationBehavior,
|
||||||
)
|
)
|
||||||
from .magic_behavior import MagicBehavior
|
from .magic_behavior import MagicBehavior
|
||||||
from .ripple_behavior import CircularRippleBehavior, RectangularRippleBehavior
|
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 .touch_behavior import TouchBehavior
|
||||||
|
|
||||||
from .hover_behavior import HoverBehavior # isort:skip
|
from .hover_behavior import HoverBehavior # isort:skip
|
||||||
|
|
|
@ -7,9 +7,8 @@ Behaviors/Background Color
|
||||||
|
|
||||||
__all__ = ("BackgroundColorBehavior", "SpecificBackgroundColorBehavior")
|
__all__ = ("BackgroundColorBehavior", "SpecificBackgroundColorBehavior")
|
||||||
|
|
||||||
from typing import List, Union
|
from typing import List
|
||||||
|
|
||||||
from kivy.animation import Animation
|
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
|
@ -25,6 +24,8 @@ from kivy.utils import get_color_from_hex
|
||||||
from kivymd.color_definitions import hue, palette, text_colors
|
from kivymd.color_definitions import hue, palette, text_colors
|
||||||
from kivymd.theming import ThemeManager
|
from kivymd.theming import ThemeManager
|
||||||
|
|
||||||
|
from .elevation import CommonElevationBehavior
|
||||||
|
|
||||||
Builder.load_string(
|
Builder.load_string(
|
||||||
"""
|
"""
|
||||||
#:import RelativeLayout kivy.uix.relativelayout.RelativeLayout
|
#:import RelativeLayout kivy.uix.relativelayout.RelativeLayout
|
||||||
|
@ -37,7 +38,7 @@ Builder.load_string(
|
||||||
angle: self.angle
|
angle: self.angle
|
||||||
origin: self._background_origin
|
origin: self._background_origin
|
||||||
Color:
|
Color:
|
||||||
rgba: self._md_bg_color
|
rgba: self.md_bg_color
|
||||||
RoundedRectangle:
|
RoundedRectangle:
|
||||||
group: "Background_instruction"
|
group: "Background_instruction"
|
||||||
size: self.size
|
size: self.size
|
||||||
|
@ -66,7 +67,7 @@ Builder.load_string(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BackgroundColorBehavior:
|
class BackgroundColorBehavior(CommonElevationBehavior):
|
||||||
background = StringProperty()
|
background = StringProperty()
|
||||||
"""
|
"""
|
||||||
Background image path.
|
Background image path.
|
||||||
|
@ -152,26 +153,15 @@ class BackgroundColorBehavior:
|
||||||
|
|
||||||
_background_x = NumericProperty(0)
|
_background_x = NumericProperty(0)
|
||||||
_background_y = NumericProperty(0)
|
_background_y = NumericProperty(0)
|
||||||
_background_origin = ReferenceListProperty(_background_x, _background_y)
|
_background_origin = ReferenceListProperty(
|
||||||
_md_bg_color = ColorProperty([0, 0, 0, 0])
|
_background_x,
|
||||||
|
_background_y,
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, **kwarg):
|
def __init__(self, **kwarg):
|
||||||
super().__init__(**kwarg)
|
super().__init__(**kwarg)
|
||||||
self.bind(pos=self.update_background_origin)
|
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(
|
def update_background_origin(
|
||||||
self, instance_md_widget, pos: List[float]
|
self, instance_md_widget, pos: List[float]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -216,14 +206,12 @@ class SpecificBackgroundColorBehavior(BackgroundColorBehavior):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
if hasattr(self, "theme_cls"):
|
if hasattr(self, "theme_cls"):
|
||||||
self.theme_cls.bind(
|
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.bind(
|
self.theme_cls.bind(accent_palette=self._update_specific_text_color)
|
||||||
background_hue=self._update_specific_text_color,
|
self.theme_cls.bind(theme_style=self._update_specific_text_color)
|
||||||
background_palette=self._update_specific_text_color,
|
self.bind(background_hue=self._update_specific_text_color)
|
||||||
)
|
self.bind(background_palette=self._update_specific_text_color)
|
||||||
self._update_specific_text_color(None, None)
|
self._update_specific_text_color(None, None)
|
||||||
|
|
||||||
def _update_specific_text_color(
|
def _update_specific_text_color(
|
||||||
|
@ -246,17 +234,5 @@ class SpecificBackgroundColorBehavior(BackgroundColorBehavior):
|
||||||
secondary_color[3] = 0.54
|
secondary_color[3] = 0.54
|
||||||
else:
|
else:
|
||||||
secondary_color[3] = 0.7
|
secondary_color[3] = 0.7
|
||||||
|
self.specific_text_color = color
|
||||||
if (
|
self.specific_secondary_text_color = secondary_color
|
||||||
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
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ from kivy.properties import (
|
||||||
from kivy.uix.behaviors import ToggleButtonBehavior
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
|
|
||||||
|
|
||||||
class CommonRipple:
|
class CommonRipple(object):
|
||||||
"""Base class for ripple effect."""
|
"""Base class for ripple effect."""
|
||||||
|
|
||||||
ripple_rad_default = NumericProperty(1)
|
ripple_rad_default = NumericProperty(1)
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
"""
|
|
||||||
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)`.
|
|
||||||
"""
|
|
|
@ -1,156 +0,0 @@
|
||||||
"""
|
|
||||||
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`.
|
|
||||||
"""
|
|
|
@ -1,134 +0,0 @@
|
||||||
"""
|
|
||||||
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,104 +14,61 @@ example:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
|
||||||
|
from kivymd.uix.button import MDRectangleFlatButton
|
||||||
|
|
||||||
from kivy.lang import Builder
|
KV = '''
|
||||||
|
Screen:
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
MDBoxLayout:
|
||||||
from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
|
adaptive_size: True
|
||||||
from kivymd.uix.button import MDFlatButton
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
|
||||||
KV = '''
|
MyToggleButton:
|
||||||
MDScreen:
|
text: "Show ads"
|
||||||
|
group: "x"
|
||||||
|
|
||||||
MDBoxLayout:
|
MyToggleButton:
|
||||||
adaptive_size: True
|
text: "Do not show ads"
|
||||||
spacing: "12dp"
|
group: "x"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MyToggleButton:
|
MyToggleButton:
|
||||||
text: "Show ads"
|
text: "Does not matter"
|
||||||
group: "x"
|
group: "x"
|
||||||
|
'''
|
||||||
MyToggleButton:
|
|
||||||
text: "Do not show ads"
|
|
||||||
group: "x"
|
|
||||||
|
|
||||||
MyToggleButton:
|
|
||||||
text: "Does not matter"
|
|
||||||
group: "x"
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class MyToggleButton(MDFlatButton, MDToggleButton):
|
class MyToggleButton(MDRectangleFlatButton, MDToggleButton):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
self.background_down = self.theme_cls.primary_color
|
self.background_down = self.theme_cls.primary_light
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
class Test(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(KV)
|
||||||
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
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toggle-button-1.gif
|
||||||
:align: center
|
: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
|
You can inherit the ``MyToggleButton`` class only from the following classes
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -131,7 +88,6 @@ from kivy.properties import BooleanProperty, ColorProperty
|
||||||
from kivy.uix.behaviors import ToggleButtonBehavior
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
|
|
||||||
from kivymd.uix.button import (
|
from kivymd.uix.button import (
|
||||||
ButtonContentsIconText,
|
|
||||||
MDFillRoundFlatButton,
|
MDFillRoundFlatButton,
|
||||||
MDFillRoundFlatIconButton,
|
MDFillRoundFlatIconButton,
|
||||||
MDFlatButton,
|
MDFlatButton,
|
||||||
|
@ -193,8 +149,7 @@ class MDToggleButton(ToggleButtonBehavior):
|
||||||
# Do the object inherited from the "supported" buttons?
|
# Do the object inherited from the "supported" buttons?
|
||||||
if not issubclass(self.__class__, classinfo):
|
if not issubclass(self.__class__, classinfo):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Class {self.__class__} must be inherited from one of the "
|
f"Class {self.__class__} must be inherited from one of the classes in the list {classinfo}"
|
||||||
f"classes in the list {classinfo}"
|
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
not self.background_normal
|
not self.background_normal
|
||||||
|
@ -210,12 +165,10 @@ class MDToggleButton(ToggleButtonBehavior):
|
||||||
):
|
):
|
||||||
self.__is_filled = True
|
self.__is_filled = True
|
||||||
self.background_normal = self.theme_cls.primary_color
|
self.background_normal = self.theme_cls.primary_color
|
||||||
# If not background_normal must be the same as the inherited one.
|
# If not the background_normal must be the same as the inherited one:
|
||||||
else:
|
else:
|
||||||
self.background_normal = (
|
self.background_normal = self.md_bg_color[:]
|
||||||
self.md_bg_color[:] if self.md_bg_color else (0, 0, 0, 0)
|
# If no background_down is setted:
|
||||||
)
|
|
||||||
# If no background_down is setter.
|
|
||||||
if (
|
if (
|
||||||
not self.background_down
|
not self.background_down
|
||||||
): # This means that if the value == [] or None will return True.
|
): # This means that if the value == [] or None will return True.
|
||||||
|
@ -247,6 +200,3 @@ class MDToggleButton(ToggleButtonBehavior):
|
||||||
): # If the background is transparent, the font color must be the
|
): # If the background is transparent, the font color must be the
|
||||||
# primary color.
|
# primary color.
|
||||||
self.text_color = self.font_color_normal
|
self.text_color = self.font_color_normal
|
||||||
|
|
||||||
if issubclass(self.__class__, ButtonContentsIconText):
|
|
||||||
self.icon_color = self.text_color
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#:import sm kivy.uix.screenmanager
|
||||||
#:import STANDARD_INCREMENT kivymd.material_resources.STANDARD_INCREMENT
|
#:import STANDARD_INCREMENT kivymd.material_resources.STANDARD_INCREMENT
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +7,9 @@
|
||||||
height:
|
height:
|
||||||
STANDARD_INCREMENT if app.theme_cls.material_style == "M2" else "80dp"
|
STANDARD_INCREMENT if app.theme_cls.material_style == "M2" else "80dp"
|
||||||
|
|
||||||
ScreenManager:
|
MDScreenManager:
|
||||||
id: tab_manager
|
id: tab_manager
|
||||||
transition: root.transition(duration=root.transition_duration)
|
transition: sm.FadeTransition(duration=.2)
|
||||||
on_current:
|
on_current:
|
||||||
root.dispatch( \
|
root.dispatch( \
|
||||||
"on_switch_tabs", \
|
"on_switch_tabs", \
|
||||||
|
@ -95,7 +96,7 @@
|
||||||
radius: [16,]
|
radius: [16,]
|
||||||
size: root._selected_region_width, dp(32)
|
size: root._selected_region_width, dp(32)
|
||||||
pos:
|
pos:
|
||||||
self.center_x - root._selected_region_width / 2, \
|
self.center_x - self.width - dp(8), \
|
||||||
self.center_y - (dp(16))
|
self.center_y - (dp(16))
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
|
|
|
@ -62,120 +62,59 @@ For ease of understanding, this code works like this:
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
from kivy.lang import Builder
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
class Test(MDApp):
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.material_style = "M3"
|
self.theme_cls.material_style = "M3"
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(
|
||||||
return Builder.load_string(
|
'''
|
||||||
'''
|
MDScreen:
|
||||||
MDScreen:
|
|
||||||
|
|
||||||
MDBottomNavigation:
|
MDBottomNavigation:
|
||||||
#panel_color: "#eeeaea"
|
panel_color: "#eeeaea"
|
||||||
selected_color_background: "orange"
|
selected_color_background: "#97ecf8"
|
||||||
text_color_active: "lightgrey"
|
text_color_active: 0, 0, 0, 1
|
||||||
|
|
||||||
MDBottomNavigationItem:
|
MDBottomNavigationItem:
|
||||||
name: 'screen 1'
|
name: 'screen 1'
|
||||||
text: 'Mail'
|
text: 'Mail'
|
||||||
icon: 'gmail'
|
icon: 'gmail'
|
||||||
badge_icon: "numeric-10"
|
badge_icon: "numeric-10"
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
text: 'Mail'
|
text: 'Mail'
|
||||||
halign: 'center'
|
halign: 'center'
|
||||||
|
|
||||||
MDBottomNavigationItem:
|
MDBottomNavigationItem:
|
||||||
name: 'screen 2'
|
name: 'screen 2'
|
||||||
text: 'Twitter'
|
text: 'Discord'
|
||||||
icon: 'twitter'
|
icon: 'discord'
|
||||||
badge_icon: "numeric-5"
|
badge_icon: "numeric-5"
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
text: 'Twitter'
|
text: 'Discord'
|
||||||
halign: 'center'
|
halign: 'center'
|
||||||
|
|
||||||
MDBottomNavigationItem:
|
MDBottomNavigationItem:
|
||||||
name: 'screen 3'
|
name: 'screen 3'
|
||||||
text: 'LinkedIN'
|
text: 'LinkedIN'
|
||||||
icon: 'linkedin'
|
icon: 'linkedin'
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
text: 'LinkedIN'
|
text: 'LinkedIN'
|
||||||
halign: 'center'
|
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
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/bottom-navigation.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -253,13 +192,16 @@ from kivy.properties import (
|
||||||
)
|
)
|
||||||
from kivy.uix.behaviors import ButtonBehavior
|
from kivy.uix.behaviors import ButtonBehavior
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.uix.screenmanager import FadeTransition, ScreenManagerException
|
from kivy.uix.screenmanager import ScreenManagerException
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.material_resources import STANDARD_INCREMENT
|
from kivymd.material_resources import STANDARD_INCREMENT
|
||||||
from kivymd.theming import ThemableBehavior, ThemeManager
|
from kivymd.theming import ThemableBehavior, ThemeManager
|
||||||
from kivymd.uix.anchorlayout import MDAnchorLayout
|
from kivymd.uix.anchorlayout import MDAnchorLayout
|
||||||
from kivymd.uix.behaviors import CommonElevationBehavior, DeclarativeBehavior
|
from kivymd.uix.behaviors import (
|
||||||
|
DeclarativeBehavior,
|
||||||
|
FakeRectangularElevationBehavior,
|
||||||
|
)
|
||||||
from kivymd.uix.behaviors.backgroundcolor_behavior import (
|
from kivymd.uix.behaviors.backgroundcolor_behavior import (
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
)
|
)
|
||||||
|
@ -471,28 +413,6 @@ class MDBottomNavigationItem(MDTab):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*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:
|
def on_tab_press(self, *args) -> None:
|
||||||
"""Called when clicking on a panel item."""
|
"""Called when clicking on a panel item."""
|
||||||
|
|
||||||
|
@ -500,13 +420,28 @@ class MDBottomNavigationItem(MDTab):
|
||||||
bottom_navigation_header_object = (
|
bottom_navigation_header_object = (
|
||||||
bottom_navigation_object.previous_tab.header
|
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.previous_tab is not self:
|
||||||
self.animate_header(
|
if bottom_navigation_object.use_text:
|
||||||
bottom_navigation_object, bottom_navigation_header_object
|
Animation(_label_font_size=sp(12), d=0.1).start(
|
||||||
)
|
bottom_navigation_object.previous_tab.header
|
||||||
|
)
|
||||||
super().on_tab_press(*args)
|
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
|
||||||
|
|
||||||
def on_disabled(
|
def on_disabled(
|
||||||
self, instance_bottom_navigation_item, disabled_value: bool
|
self, instance_bottom_navigation_item, disabled_value: bool
|
||||||
|
@ -563,26 +498,6 @@ class MDBottomNavigation(DeclarativeBehavior, TabbedPanelBase):
|
||||||
.. versionadded:: 1.0.0
|
.. 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_normal = ColorProperty([1, 1, 1, 1])
|
||||||
"""
|
"""
|
||||||
Text color of the label when it is not selected.
|
Text color of the label when it is not selected.
|
||||||
|
@ -857,6 +772,8 @@ class MDBottomNavigation(DeclarativeBehavior, TabbedPanelBase):
|
||||||
|
|
||||||
|
|
||||||
class MDBottomNavigationBar(
|
class MDBottomNavigationBar(
|
||||||
ThemableBehavior, CommonElevationBehavior, MDFloatLayout
|
ThemableBehavior,
|
||||||
|
FakeRectangularElevationBehavior,
|
||||||
|
MDFloatLayout,
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -34,7 +34,7 @@ Usage :class:`~MDListBottomSheet`
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: "Example BottomSheet"
|
title: "Example BottomSheet"
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
elevation: 4
|
elevation: 10
|
||||||
|
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
text: "Open list bottom sheet"
|
text: "Open list bottom sheet"
|
||||||
|
@ -94,7 +94,7 @@ which will be used as an icon to the left of the item:
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: 'Example BottomSheet'
|
title: 'Example BottomSheet'
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
elevation: 4
|
elevation: 10
|
||||||
|
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
text: "Open grid bottom sheet"
|
text: "Open grid bottom sheet"
|
||||||
|
@ -180,7 +180,7 @@ which will be used as an icon to the left of the item:
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: 'Example BottomSheet'
|
title: 'Example BottomSheet'
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
elevation: 4
|
elevation: 10
|
||||||
|
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
text: "Open custom bottom sheet"
|
text: "Open custom bottom sheet"
|
||||||
|
|
|
@ -93,8 +93,6 @@ from kivymd.uix.behaviors import DeclarativeBehavior
|
||||||
|
|
||||||
class MDBoxLayout(DeclarativeBehavior, BoxLayout, MDAdaptiveWidget):
|
class MDBoxLayout(DeclarativeBehavior, BoxLayout, MDAdaptiveWidget):
|
||||||
"""
|
"""
|
||||||
Box layout class.
|
Box layout class. For more information, see in the
|
||||||
|
|
||||||
For more information, see in the
|
|
||||||
:class:`~kivy.uix.boxlayout.BoxLayout` class documentation.
|
:class:`~kivy.uix.boxlayout.BoxLayout` class documentation.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# NOQA F401
|
# NOQA F401
|
||||||
from .button import (
|
from .button import (
|
||||||
BaseButton,
|
BaseButton,
|
||||||
ButtonContentsIconText,
|
|
||||||
MDFillRoundFlatButton,
|
MDFillRoundFlatButton,
|
||||||
MDFillRoundFlatIconButton,
|
MDFillRoundFlatIconButton,
|
||||||
MDFlatButton,
|
MDFlatButton,
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
Clear
|
Clear
|
||||||
Color:
|
Color:
|
||||||
rgba:
|
rgba:
|
||||||
self._md_bg_color \
|
(self._md_bg_color or [0.0, 0.0, 0.0, 0.0]) \
|
||||||
if not self.disabled else \
|
if not self.disabled else \
|
||||||
self._md_bg_color_disabled
|
(self._md_bg_color_disabled or [0.0, 0.0, 0.0, 0.0])
|
||||||
RoundedRectangle:
|
RoundedRectangle:
|
||||||
size: self.size
|
size: self.size
|
||||||
pos: self.pos
|
pos: self.pos
|
||||||
|
@ -13,17 +13,19 @@
|
||||||
radius: [root._radius, ]
|
radius: [root._radius, ]
|
||||||
Color:
|
Color:
|
||||||
rgba:
|
rgba:
|
||||||
root._line_color \
|
root._line_color or [0.0, 0.0, 0.0, 0.0] \
|
||||||
if not root.disabled else \
|
if not root.disabled else \
|
||||||
(root._line_color_disabled or self._disabled_color)
|
( \
|
||||||
|
root._line_color_disabled \
|
||||||
|
or self._disabled_color \
|
||||||
|
or [0.0, 0.0, 0.0, 0.0] \
|
||||||
|
)
|
||||||
Line:
|
Line:
|
||||||
width: root.line_width
|
width: root.line_width
|
||||||
rounded_rectangle:
|
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, \
|
root._radius, root._radius, root._radius, root._radius, \
|
||||||
self.height \
|
self.height)
|
||||||
)
|
|
||||||
|
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
anchor_x: root.halign
|
anchor_x: root.halign
|
||||||
|
@ -31,28 +33,21 @@
|
||||||
_round_rad: [self._radius] * 4
|
_round_rad: [self._radius] * 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ButtonContentsText>
|
<ButtonContentsText>
|
||||||
lbl_txt: lbl_txt
|
lbl_txt: lbl_txt
|
||||||
width:
|
width:
|
||||||
max( \
|
max(root._min_width, \
|
||||||
root._min_width, \
|
root.padding[0] + lbl_txt.texture_size[0] + root.padding[2])
|
||||||
root.padding[0] + lbl_txt.texture_size[0] + root.padding[2] \
|
|
||||||
)
|
|
||||||
size_hint_min_x:
|
size_hint_min_x:
|
||||||
max( \
|
max(root._min_width, \
|
||||||
root._min_width, \
|
root.padding[0] + lbl_txt.texture_size[0] + root.padding[2])
|
||||||
root.padding[0] + lbl_txt.texture_size[0] + root.padding[2] \
|
|
||||||
)
|
|
||||||
height:
|
height:
|
||||||
max( \
|
max(root._min_height, \
|
||||||
root._min_height, \
|
root.padding[1] + lbl_txt.texture_size[1] + root.padding[3])
|
||||||
root.padding[1] + lbl_txt.texture_size[1] + root.padding[3] \
|
|
||||||
)
|
|
||||||
size_hint_min_y:
|
size_hint_min_y:
|
||||||
max( \
|
max(root._min_height, \
|
||||||
root._min_height, \
|
root.padding[1] + lbl_txt.texture_size[1] + root.padding[3])
|
||||||
root.padding[1] + lbl_txt.texture_size[1] + root.padding[3] \
|
|
||||||
)
|
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
id: lbl_txt
|
id: lbl_txt
|
||||||
|
@ -89,10 +84,7 @@
|
||||||
# This is only a temporary fix and does not fix the cause of the error.
|
# 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) \
|
(root._icon_color if root._icon_color else root.theme_cls.text_color) \
|
||||||
if not root.disabled else \
|
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:
|
on_icon:
|
||||||
if self.icon not in md_icons.keys(): self.size_hint = (1, 1)
|
if self.icon not in md_icons.keys(): self.size_hint = (1, 1)
|
||||||
theme_text_color: root._theme_icon_color
|
theme_text_color: root._theme_icon_color
|
||||||
|
@ -139,7 +131,7 @@
|
||||||
id: box
|
id: box
|
||||||
adaptive_size: True
|
adaptive_size: True
|
||||||
padding: 0
|
padding: 0
|
||||||
spacing: "8dp"
|
spacing: "4dp"
|
||||||
|
|
||||||
MDIcon:
|
MDIcon:
|
||||||
id: lbl_ic
|
id: lbl_ic
|
||||||
|
@ -201,21 +193,48 @@
|
||||||
radius: [self.height / 2]
|
radius: [self.height / 2]
|
||||||
|
|
||||||
|
|
||||||
<MDFloatingRootButton>
|
<BaseFloatingRootButton>
|
||||||
theme_text_color: "Custom"
|
theme_text_color: "Custom"
|
||||||
md_bg_color: self.theme_cls.primary_color
|
md_bg_color: self.theme_cls.primary_color
|
||||||
|
|
||||||
|
|
||||||
<MDFloatingLabel>
|
|
||||||
padding_x: "8dp"
|
|
||||||
padding_y: "8dp"
|
|
||||||
adaptive_size: True
|
|
||||||
theme_text_color: "Custom"
|
|
||||||
|
|
||||||
canvas.before:
|
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:
|
Color:
|
||||||
rgba: self.bg_color
|
rgba:
|
||||||
|
self.theme_cls.primary_color \
|
||||||
|
if not root.bg_color else \
|
||||||
|
root.bg_color
|
||||||
RoundedRectangle:
|
RoundedRectangle:
|
||||||
size: self.size
|
|
||||||
pos: self.pos
|
pos: self.pos
|
||||||
radius: self.radius
|
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
|
||||||
|
|
|
@ -2,6 +2,17 @@
|
||||||
md_bg_color: app.theme_cls.divider_color
|
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>
|
<MDSeparator>
|
||||||
md_bg_color:
|
md_bg_color:
|
||||||
self.theme_cls.divider_color \
|
self.theme_cls.divider_color \
|
||||||
|
|
|
@ -26,6 +26,26 @@ Components/Card
|
||||||
MDCard
|
MDCard
|
||||||
------
|
------
|
||||||
|
|
||||||
|
.. warning:: Starting from the KivyMD 1.1.0 library version, it is necessary
|
||||||
|
to manually inherit the card class from one of the ``Elevation`` classes
|
||||||
|
from ``kivymd/uix/behaviors/elevation.py`` module to draw the card shadow.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
|
from kivymd.uix.card import MDCard
|
||||||
|
|
||||||
|
|
||||||
|
class MD3Card(MDCard, RoundedRectangularElevationBehavior):
|
||||||
|
'''Implements a material design v3 card.'''
|
||||||
|
|
||||||
|
It actually allows for better control over the providers that implement the
|
||||||
|
rendering of the shadows.
|
||||||
|
|
||||||
|
.. note:: You can read more information about the classes that implement the
|
||||||
|
rendering of shadows on this
|
||||||
|
`documentation page <https://kivymd.readthedocs.io/en/latest/behaviors/elevation/>`_.
|
||||||
|
|
||||||
An example of the implementation of a card in the style of material design version 3
|
An example of the implementation of a card in the style of material design version 3
|
||||||
------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -39,6 +59,7 @@ An example of the implementation of a card in the style of material design versi
|
||||||
from kivy.properties import StringProperty
|
from kivy.properties import StringProperty
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
|
@ -72,7 +93,7 @@ An example of the implementation of a card in the style of material design versi
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class MD3Card(MDCard):
|
class MD3Card(MDCard, RoundedRectangularElevationBehavior):
|
||||||
'''Implements a material design v3 card.'''
|
'''Implements a material design v3 card.'''
|
||||||
|
|
||||||
text = StringProperty()
|
text = StringProperty()
|
||||||
|
@ -105,6 +126,7 @@ An example of the implementation of a card in the style of material design versi
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.button import MDIconButton
|
from kivymd.uix.button import MDIconButton
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
@ -113,7 +135,7 @@ An example of the implementation of a card in the style of material design versi
|
||||||
from kivymd.uix.screen import MDScreen
|
from kivymd.uix.screen import MDScreen
|
||||||
|
|
||||||
|
|
||||||
class MD3Card(MDCard):
|
class MD3Card(MDCard, RoundedRectangularElevationBehavior):
|
||||||
'''Implements a material design v3 card.'''
|
'''Implements a material design v3 card.'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,6 +170,7 @@ An example of the implementation of a card in the style of material design versi
|
||||||
adaptive_size=True,
|
adaptive_size=True,
|
||||||
color="grey",
|
color="grey",
|
||||||
pos=("12dp", "12dp"),
|
pos=("12dp", "12dp"),
|
||||||
|
bold=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
line_color=(0.2, 0.2, 0.2, 0.8),
|
line_color=(0.2, 0.2, 0.2, 0.8),
|
||||||
|
@ -232,9 +255,10 @@ End full code
|
||||||
|
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
|
spacing: "10dp"
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
elevation: 4
|
elevation: 10
|
||||||
title: "MDCardSwipe"
|
title: "MDCardSwipe"
|
||||||
|
|
||||||
MDScrollView:
|
MDScrollView:
|
||||||
|
@ -262,7 +286,7 @@ End full code
|
||||||
'''Creates a list of cards.'''
|
'''Creates a list of cards.'''
|
||||||
|
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
self.root.ids.md_list.add_widget(
|
self.screen.ids.md_list.add_widget(
|
||||||
SwipeToDeleteItem(text=f"One-line item {i}")
|
SwipeToDeleteItem(text=f"One-line item {i}")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -292,7 +316,7 @@ End full code
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDBoxLayout(
|
MDBoxLayout(
|
||||||
MDTopAppBar(
|
MDTopAppBar(
|
||||||
elevation=4,
|
elevation=10,
|
||||||
title="MDCardSwipe",
|
title="MDCardSwipe",
|
||||||
),
|
),
|
||||||
MDScrollView(
|
MDScrollView(
|
||||||
|
@ -304,6 +328,7 @@ End full code
|
||||||
),
|
),
|
||||||
id="box",
|
id="box",
|
||||||
orientation="vertical",
|
orientation="vertical",
|
||||||
|
spacing="10dp",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -401,7 +426,7 @@ You can use this event to remove items from a list:
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def on_swipe_complete(self, instance):
|
def on_swipe_complete(self, instance):
|
||||||
self.root.ids.md_list.remove_widget(instance)
|
self.screen.ids.md_list.remove_widget(instance)
|
||||||
|
|
||||||
.. tab:: Decralative python styles
|
.. tab:: Decralative python styles
|
||||||
|
|
||||||
|
@ -471,9 +496,10 @@ End full code
|
||||||
|
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
|
spacing: "10dp"
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
elevation: 4
|
elevation: 10
|
||||||
title: "MDCardSwipe"
|
title: "MDCardSwipe"
|
||||||
|
|
||||||
MDScrollView:
|
MDScrollView:
|
||||||
|
@ -534,7 +560,7 @@ End full code
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDBoxLayout(
|
MDBoxLayout(
|
||||||
MDTopAppBar(
|
MDTopAppBar(
|
||||||
elevation=4,
|
elevation=10,
|
||||||
title="MDCardSwipe",
|
title="MDCardSwipe",
|
||||||
),
|
),
|
||||||
MDScrollView(
|
MDScrollView(
|
||||||
|
@ -546,6 +572,7 @@ End full code
|
||||||
),
|
),
|
||||||
id="box",
|
id="box",
|
||||||
orientation="vertical",
|
orientation="vertical",
|
||||||
|
spacing="10dp",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -603,21 +630,26 @@ Focus behavior
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
|
from kivymd.uix.card import MDCard
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
|
||||||
MDCard:
|
ElevationCard:
|
||||||
size_hint: .7, .4
|
size_hint: .7, .4
|
||||||
focus_behavior: True
|
focus_behavior: True
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
md_bg_color: "darkgrey"
|
md_bg_color: "darkgrey"
|
||||||
unfocus_color: "darkgrey"
|
unfocus_color: "darkgrey"
|
||||||
focus_color: "grey"
|
focus_color: "grey"
|
||||||
elevation: 6
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class ElevationCard(MDCard, FakeRectangularElevationBehavior):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
self.theme_cls.theme_style = "Dark"
|
||||||
|
@ -631,23 +663,27 @@ Focus behavior
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
from kivymd.uix.screen import MDScreen
|
from kivymd.uix.screen import MDScreen
|
||||||
|
|
||||||
|
|
||||||
|
class ElevationCard(MDCard, FakeRectangularElevationBehavior):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
self.theme_cls.theme_style = "Dark"
|
||||||
return (
|
return (
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDCard(
|
ElevationCard(
|
||||||
size_hint=(0.7, 0.4),
|
size_hint=(0.7, 0.4),
|
||||||
focus_behavior=True,
|
focus_behavior=True,
|
||||||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
||||||
md_bg_color="darkgrey",
|
md_bg_color="darkgrey",
|
||||||
unfocus_color="darkgrey",
|
unfocus_color="darkgrey",
|
||||||
focus_color="grey",
|
focus_color="grey",
|
||||||
elevation=6,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -655,6 +691,7 @@ Focus behavior
|
||||||
|
|
||||||
Example().run()
|
Example().run()
|
||||||
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/card-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/card-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
|
@ -695,14 +732,12 @@ from kivy.properties import (
|
||||||
VariableListProperty,
|
VariableListProperty,
|
||||||
)
|
)
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.utils import get_color_from_hex
|
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.color_definitions import colors
|
from kivymd.color_definitions import colors
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import (
|
from kivymd.uix.behaviors import (
|
||||||
BackgroundColorBehavior,
|
BackgroundColorBehavior,
|
||||||
CommonElevationBehavior,
|
|
||||||
DeclarativeBehavior,
|
DeclarativeBehavior,
|
||||||
RectangularRippleBehavior,
|
RectangularRippleBehavior,
|
||||||
)
|
)
|
||||||
|
@ -746,7 +781,6 @@ class MDCard(
|
||||||
ThemableBehavior,
|
ThemableBehavior,
|
||||||
BackgroundColorBehavior,
|
BackgroundColorBehavior,
|
||||||
RectangularRippleBehavior,
|
RectangularRippleBehavior,
|
||||||
CommonElevationBehavior,
|
|
||||||
FocusBehavior,
|
FocusBehavior,
|
||||||
BoxLayout,
|
BoxLayout,
|
||||||
):
|
):
|
||||||
|
@ -766,6 +800,14 @@ class MDCard(
|
||||||
and defaults to `False`.
|
and defaults to `False`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
elevation = NumericProperty(None, allownone=True)
|
||||||
|
"""
|
||||||
|
Elevation value.
|
||||||
|
|
||||||
|
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
||||||
|
and defaults to 1.
|
||||||
|
"""
|
||||||
|
|
||||||
radius = VariableListProperty([dp(6), dp(6), dp(6), dp(6)])
|
radius = VariableListProperty([dp(6), dp(6), dp(6), dp(6)])
|
||||||
"""
|
"""
|
||||||
Card radius by default.
|
Card radius by default.
|
||||||
|
@ -789,16 +831,15 @@ class MDCard(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_bg_color_map = (
|
_bg_color_map = (
|
||||||
get_color_from_hex(colors["Light"]["CardsDialogs"]),
|
colors["Light"]["CardsDialogs"],
|
||||||
get_color_from_hex(colors["Dark"]["CardsDialogs"]),
|
colors["Dark"]["CardsDialogs"],
|
||||||
[1.0, 1.0, 1.0, 0.0],
|
[1.0, 1.0, 1.0, 0.0],
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.theme_cls.bind(
|
self.theme_cls.bind(theme_style=self.update_md_bg_color)
|
||||||
material_style=self.set_style, theme_style=self.update_md_bg_color
|
self.theme_cls.bind(material_style=self.set_style)
|
||||||
)
|
|
||||||
Clock.schedule_once(self.set_style)
|
Clock.schedule_once(self.set_style)
|
||||||
Clock.schedule_once(
|
Clock.schedule_once(
|
||||||
lambda x: self.on_ripple_behavior(0, self.ripple_behavior)
|
lambda x: self.on_ripple_behavior(0, self.ripple_behavior)
|
||||||
|
@ -807,9 +848,7 @@ class MDCard(
|
||||||
|
|
||||||
def update_md_bg_color(self, instance_card, theme_style: str) -> None:
|
def update_md_bg_color(self, instance_card, theme_style: str) -> None:
|
||||||
if self.md_bg_color in self._bg_color_map:
|
if self.md_bg_color in self._bg_color_map:
|
||||||
self.md_bg_color = get_color_from_hex(
|
self.md_bg_color = colors[theme_style]["CardsDialogs"]
|
||||||
colors[theme_style]["CardsDialogs"]
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_style(self, *args) -> None:
|
def set_style(self, *args) -> None:
|
||||||
self.set_radius()
|
self.set_radius()
|
||||||
|
@ -826,7 +865,7 @@ class MDCard(
|
||||||
if self.style == "outlined" or self.style == "filled":
|
if self.style == "outlined" or self.style == "filled":
|
||||||
self.elevation = 0
|
self.elevation = 0
|
||||||
elif self.style == "elevated":
|
elif self.style == "elevated":
|
||||||
self.elevation = 2
|
self.elevation = 1
|
||||||
|
|
||||||
def set_radius(self) -> None:
|
def set_radius(self) -> None:
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -132,7 +132,7 @@ Use with elevation
|
||||||
icon_right: "close-circle-outline"
|
icon_right: "close-circle-outline"
|
||||||
line_color: app.theme_cls.disabled_hint_text_color
|
line_color: app.theme_cls.disabled_hint_text_color
|
||||||
md_bg_color: 1, 0, 0, .5
|
md_bg_color: 1, 0, 0, .5
|
||||||
elevation: 4
|
elevation: 12
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-elevation.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/chip-with-elevation.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -304,6 +304,7 @@ __all__ = ("MDChip",)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from kivy import Logger
|
||||||
from kivy.animation import Animation
|
from kivy.animation import Animation
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.metrics import dp
|
from kivy.metrics import dp
|
||||||
|
@ -313,13 +314,14 @@ from kivy.uix.behaviors import ButtonBehavior
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import (
|
from kivymd.uix.behaviors import (
|
||||||
CommonElevationBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
RectangularRippleBehavior,
|
RectangularRippleBehavior,
|
||||||
ScaleBehavior,
|
|
||||||
TouchBehavior,
|
TouchBehavior,
|
||||||
)
|
)
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.label import MDIcon
|
from kivymd.uix.label import MDIcon
|
||||||
|
from kivymd.uix.stacklayout import MDStackLayout
|
||||||
|
from kivymd.uix.templates import ScaleWidget
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.join(uix_path, "chip", "chip.kv"), encoding="utf-8"
|
os.path.join(uix_path, "chip", "chip.kv"), encoding="utf-8"
|
||||||
|
@ -328,12 +330,12 @@ with open(
|
||||||
|
|
||||||
|
|
||||||
class MDChip(
|
class MDChip(
|
||||||
MDBoxLayout,
|
|
||||||
ThemableBehavior,
|
ThemableBehavior,
|
||||||
RectangularRippleBehavior,
|
RectangularRippleBehavior,
|
||||||
ButtonBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
CommonElevationBehavior,
|
|
||||||
TouchBehavior,
|
TouchBehavior,
|
||||||
|
ButtonBehavior,
|
||||||
|
MDBoxLayout,
|
||||||
):
|
):
|
||||||
text = StringProperty()
|
text = StringProperty()
|
||||||
"""
|
"""
|
||||||
|
@ -454,7 +456,7 @@ class MDChip(
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
|
|
||||||
class MDScalableCheckIcon(MDIcon, ScaleBehavior):
|
class MDScalableCheckIcon(MDIcon, ScaleWidget):
|
||||||
pos_hint = {"center_y": 0.5}
|
pos_hint = {"center_y": 0.5}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#:import DEVICE_TYPE kivymd.material_resources.DEVICE_TYPE
|
#:import DEVICE_TYPE kivymd.material_resources.DEVICE_TYPE
|
||||||
|
#:import FakeRectangularElevationBehavior kivymd.uix.behaviors.FakeRectangularElevationBehavior
|
||||||
|
|
||||||
|
|
||||||
<CellRow>
|
<CellRow>
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
height: self.minimum_height
|
height: self.minimum_height
|
||||||
spacing: "4dp"
|
spacing: "4dp"
|
||||||
tooltip_text: root.tooltip if root.tooltip else root.text
|
tooltip_text: root.text
|
||||||
|
|
||||||
BoxLayout:
|
BoxLayout:
|
||||||
id: box
|
id: box
|
||||||
|
@ -174,11 +175,7 @@
|
||||||
font_size: "14sp"
|
font_size: "14sp"
|
||||||
on_release: root.table_data.open_pagination_menu()
|
on_release: root.table_data.open_pagination_menu()
|
||||||
text:
|
text:
|
||||||
"{}".format( \
|
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)}"
|
||||||
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:
|
Widget:
|
||||||
size_hint_x: None
|
size_hint_x: None
|
||||||
|
@ -195,11 +192,9 @@
|
||||||
if root.theme_cls.theme_style == "Dark" else \
|
if root.theme_cls.theme_style == "Dark" else \
|
||||||
(0, 0, 0, 1)
|
(0, 0, 0, 1)
|
||||||
text:
|
text:
|
||||||
"1-{} of {}".format( \
|
f"1-" \
|
||||||
root.table_data.rows_num \
|
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)} " \
|
||||||
if root.table_data.rows_num > len(root.table_data.row_data) else \
|
f"of {len(root.table_data.row_data)}"
|
||||||
len(root.table_data.row_data), len(root.table_data.row_data) \
|
|
||||||
)
|
|
||||||
|
|
||||||
MDIconButton:
|
MDIconButton:
|
||||||
id: button_back
|
id: button_back
|
||||||
|
@ -222,7 +217,7 @@
|
||||||
on_release: root.table_data.set_next_row_data_parts("forward")
|
on_release: root.table_data.set_next_row_data_parts("forward")
|
||||||
|
|
||||||
|
|
||||||
<TableContainer@MDCard>
|
<TableContainer@MDCard+FakeRectangularElevationBehavior>
|
||||||
|
|
||||||
|
|
||||||
<MDDataTable>
|
<MDDataTable>
|
||||||
|
|
|
@ -11,6 +11,19 @@ Components/DataTables
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-previous.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-previous.png
|
||||||
:align: center
|
: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.
|
.. 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
|
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
|
while you're defining the table columns. Be aware that the sorting function
|
||||||
|
@ -146,15 +159,6 @@ class CellHeader(MDTooltip, BoxLayout):
|
||||||
and defaults to `''`.
|
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.
|
# TODO: Added example.
|
||||||
sort_action = ObjectProperty()
|
sort_action = ObjectProperty()
|
||||||
"""
|
"""
|
||||||
|
@ -336,19 +340,11 @@ class TableHeader(ThemableBehavior, ScrollView):
|
||||||
CellHeader(
|
CellHeader(
|
||||||
text=col_heading[0],
|
text=col_heading[0],
|
||||||
sort_action=col_heading[2],
|
sort_action=col_heading[2],
|
||||||
tooltip=col_heading[3],
|
|
||||||
width=self.cols_minimum[i],
|
width=self.cols_minimum[i],
|
||||||
table_data=self.table_data,
|
table_data=self.table_data,
|
||||||
is_sorted=(col_heading[0] == self.sorted_on),
|
is_sorted=(col_heading[0] == self.sorted_on),
|
||||||
sorted_order=self.sorted_order,
|
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
|
if len(col_heading) == 3
|
||||||
else CellHeader(
|
else CellHeader(
|
||||||
text=col_heading[0],
|
text=col_heading[0],
|
||||||
|
@ -360,9 +356,6 @@ class TableHeader(ThemableBehavior, ScrollView):
|
||||||
else:
|
else:
|
||||||
# Sets the text in the first cell.
|
# Sets the text in the first cell.
|
||||||
self.ids.first_cell.text = col_heading[0]
|
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.ids.separator.height = 0
|
||||||
self.ids.first_cell.width = self.cols_minimum[i]
|
self.ids.first_cell.width = self.cols_minimum[i]
|
||||||
|
|
||||||
|
@ -772,9 +765,6 @@ class TablePagination(ThemableBehavior, MDBoxLayout):
|
||||||
|
|
||||||
class MDDataTable(ThemableBehavior, AnchorLayout):
|
class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
"""
|
"""
|
||||||
See :class:`~kivy.uix.anchorlayout.AnchorLayout` class documentation for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
:Events:
|
:Events:
|
||||||
:attr:`on_row_press`
|
:attr:`on_row_press`
|
||||||
Called when a table row is clicked.
|
Called when a table row is clicked.
|
||||||
|
@ -785,6 +775,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
|
||||||
from kivy.metrics import dp
|
from kivy.metrics import dp
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
@ -923,82 +914,38 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
"""
|
"""
|
||||||
Data for header columns.
|
Data for header columns.
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Imperative python style
|
from kivy.metrics import dp
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.datatables import MDDataTable
|
||||||
from kivy.metrics import dp
|
from kivy.uix.anchorlayout import AnchorLayout
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.datatables import MDDataTable
|
|
||||||
from kivy.uix.anchorlayout import AnchorLayout
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
layout = AnchorLayout()
|
||||||
self.theme_cls.primary_palette = "Orange"
|
self.data_tables = MDDataTable(
|
||||||
|
size_hint=(0.7, 0.6),
|
||||||
layout = AnchorLayout()
|
use_pagination=True,
|
||||||
self.data_tables = MDDataTable(
|
check=True,
|
||||||
size_hint=(0.7, 0.6),
|
# name column, width column, sorting function column(optional)
|
||||||
use_pagination=True,
|
column_data=[
|
||||||
check=True,
|
("No.", dp(30)),
|
||||||
# name column, width column, sorting function column(optional), custom tooltip
|
("Status", dp(30)),
|
||||||
column_data=[
|
("Signal Name", dp(60)),
|
||||||
("No.", dp(30), None, "Custom tooltip"),
|
("Severity", dp(30)),
|
||||||
("Status", dp(30)),
|
("Stage", dp(30)),
|
||||||
("Signal Name", dp(60)),
|
("Schedule", dp(30), lambda *args: print("Sorted using Schedule")),
|
||||||
("Severity", dp(30)),
|
("Team Lead", 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
|
||||||
)
|
|
||||||
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
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-column-data.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -1113,9 +1060,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
|
|
||||||
layout = AnchorLayout()
|
layout = AnchorLayout()
|
||||||
data_tables = MDDataTable(
|
data_tables = MDDataTable(
|
||||||
size_hint=(0.9, 0.6),
|
size_hint=(0.9, 0.6),
|
||||||
|
@ -1243,7 +1187,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
"""
|
"""
|
||||||
Use or not use checkboxes for rows.
|
Use or not use checkboxes for rows.
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-check.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-check.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`check` is an :class:`~kivy.properties.BooleanProperty`
|
:attr:`check` is an :class:`~kivy.properties.BooleanProperty`
|
||||||
|
@ -1265,9 +1209,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
|
|
||||||
layout = AnchorLayout()
|
layout = AnchorLayout()
|
||||||
data_tables = MDDataTable(
|
data_tables = MDDataTable(
|
||||||
size_hint=(0.9, 0.6),
|
size_hint=(0.9, 0.6),
|
||||||
|
@ -1297,19 +1238,19 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
and defaults to `False`.
|
and defaults to `False`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
elevation = NumericProperty(4)
|
elevation = NumericProperty(8)
|
||||||
"""
|
"""
|
||||||
Table elevation.
|
Table elevation.
|
||||||
|
|
||||||
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
||||||
and defaults to `4`.
|
and defaults to `8`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
rows_num = NumericProperty(5)
|
rows_num = NumericProperty(5)
|
||||||
"""
|
"""
|
||||||
The number of rows displayed on one page of the table.
|
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-rows-num.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-use-pagination.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`rows_num` is an :class:`~kivy.properties.NumericProperty`
|
:attr:`rows_num` is an :class:`~kivy.properties.NumericProperty`
|
||||||
|
@ -1325,7 +1266,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
.. rubric:: Center
|
.. rubric:: Center
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-pos-top.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-pos-center.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. rubric:: Auto
|
.. rubric:: Auto
|
||||||
|
@ -1341,6 +1282,11 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
"""
|
"""
|
||||||
Menu height for selecting the number of displayed rows.
|
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
|
.. rubric:: 240dp
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-height-240.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-menu-height-240.png
|
||||||
|
@ -1352,7 +1298,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
background_color = ColorProperty([0, 0, 0, 0])
|
background_color = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Background color in the format (r, g, b, a) or string format.
|
Background color in the format (r, g, b, a).
|
||||||
See :attr:`~kivy.uix.modalview.ModalView.background_color`.
|
See :attr:`~kivy.uix.modalview.ModalView.background_color`.
|
||||||
|
|
||||||
Use markup strings
|
Use markup strings
|
||||||
|
@ -1369,9 +1315,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
|
|
||||||
layout = AnchorLayout()
|
layout = AnchorLayout()
|
||||||
data_tables = MDDataTable(
|
data_tables = MDDataTable(
|
||||||
size_hint=(0.9, 0.6),
|
size_hint=(0.9, 0.6),
|
||||||
|
@ -1411,8 +1354,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
background_color_header = ColorProperty(None)
|
background_color_header = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color in the format (r, g, b, a) or string format for
|
Background color for :class:`~TableHeader` class.
|
||||||
:class:`~TableHeader` class.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1432,8 +1374,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
background_color_cell = ColorProperty(None)
|
background_color_cell = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color in the format (r, g, b, a) or string format for
|
Background color for :class:`~CellRow` class.
|
||||||
:class:`~CellRow` class.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1454,8 +1395,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
|
|
||||||
background_color_selected_cell = ColorProperty(None)
|
background_color_selected_cell = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background selected color in the format (r, g, b, a) or string format for
|
Background selected color for :class:`~CellRow` class.
|
||||||
:class:`~CellRow` class.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1468,7 +1408,7 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
background_color_selected_cell="e4514f",
|
background_color_selected_cell="e4514f",
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-background-color-selected-cell.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/data-tables-background-color-selected-cell.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`background_color_selected_cell` is a :class:`~kivy.properties.ColorProperty` and
|
:attr:`background_color_selected_cell` is a :class:`~kivy.properties.ColorProperty` and
|
||||||
|
@ -1563,9 +1503,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
data_tables = None
|
data_tables = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
|
|
||||||
layout = MDFloatLayout() # root layout
|
layout = MDFloatLayout() # root layout
|
||||||
# Creating control buttons.
|
# Creating control buttons.
|
||||||
button_box = MDBoxLayout(
|
button_box = MDBoxLayout(
|
||||||
|
@ -1667,9 +1604,6 @@ class MDDataTable(ThemableBehavior, AnchorLayout):
|
||||||
data_tables = None
|
data_tables = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
|
|
||||||
layout = MDFloatLayout()
|
layout = MDFloatLayout()
|
||||||
layout.add_widget(
|
layout.add_widget(
|
||||||
MDRaisedButton(
|
MDRaisedButton(
|
||||||
|
|
|
@ -18,11 +18,7 @@
|
||||||
PopMatrix
|
PopMatrix
|
||||||
|
|
||||||
|
|
||||||
<DialogContainer@MDCard>
|
<DialogContainer@MDCard+FakeRectangularElevationBehavior>
|
||||||
shadow_color: 0.0, 0.0, 0.0, 0.0
|
|
||||||
elevation: 0
|
|
||||||
shadow_softness: 0
|
|
||||||
shadow_offset: 0, 0
|
|
||||||
|
|
||||||
|
|
||||||
<MDDialog>
|
<MDDialog>
|
||||||
|
@ -32,6 +28,7 @@
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
height: self.minimum_height
|
height: self.minimum_height
|
||||||
|
elevation: 24
|
||||||
padding: "24dp", "24dp", "8dp", "8dp"
|
padding: "24dp", "24dp", "8dp", "8dp"
|
||||||
radius: root.radius
|
radius: root.radius
|
||||||
md_bg_color:
|
md_bg_color:
|
||||||
|
|
|
@ -38,8 +38,6 @@ Usage
|
||||||
dialog = None
|
dialog = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
def show_alert_dialog(self):
|
def show_alert_dialog(self):
|
||||||
|
@ -89,7 +87,6 @@ from kivy.uix.modalview import ModalView
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.material_resources import DEVICE_TYPE
|
from kivymd.material_resources import DEVICE_TYPE
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import CommonElevationBehavior
|
|
||||||
from kivymd.uix.button import BaseButton
|
from kivymd.uix.button import BaseButton
|
||||||
from kivymd.uix.card import MDSeparator
|
from kivymd.uix.card import MDSeparator
|
||||||
from kivymd.uix.list import BaseListItem
|
from kivymd.uix.list import BaseListItem
|
||||||
|
@ -100,40 +97,7 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class BaseDialog(ThemableBehavior, ModalView, CommonElevationBehavior):
|
class BaseDialog(ThemableBehavior, ModalView):
|
||||||
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)])
|
radius = ListProperty([dp(7), dp(7), dp(7), dp(7)])
|
||||||
"""
|
"""
|
||||||
Dialog corners rounding value.
|
Dialog corners rounding value.
|
||||||
|
@ -286,22 +250,21 @@ class MDDialog(BaseDialog):
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
dialog = None
|
dialog = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(KV)
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def show_simple_dialog(self):
|
def show_simple_dialog(self):
|
||||||
if not self.dialog:
|
if not self.dialog:
|
||||||
self.dialog = MDDialog(
|
self.dialog = MDDialog(
|
||||||
title="Set backup account",
|
title="Set backup account",
|
||||||
type="simple",
|
type="simple",
|
||||||
items=[
|
items=[
|
||||||
Item(text="user01@gmail.com", source="kivymd/images/logo/kivymd-icon-128.png"),
|
Item(text="user01@gmail.com", source="user-1.png"),
|
||||||
Item(text="user02@gmail.com", source="data/logo/kivy-icon-128.png"),
|
Item(text="user02@gmail.com", source="user-2.png"),
|
||||||
],
|
Item(text="Add account", source="add-icon.png"),
|
||||||
)
|
],
|
||||||
self.dialog.open()
|
)
|
||||||
|
self.dialog.open()
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
Example().run()
|
||||||
|
@ -354,8 +317,6 @@ class MDDialog(BaseDialog):
|
||||||
dialog = None
|
dialog = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
def show_confirmation_dialog(self):
|
def show_confirmation_dialog(self):
|
||||||
|
@ -424,140 +385,71 @@ class MDDialog(BaseDialog):
|
||||||
"""
|
"""
|
||||||
Custom content class.
|
Custom content class.
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.button import MDFlatButton
|
||||||
|
from kivymd.uix.dialog import MDDialog
|
||||||
|
|
||||||
from kivy.lang import Builder
|
KV = '''
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
<Content>
|
||||||
|
orientation: "vertical"
|
||||||
|
spacing: "12dp"
|
||||||
|
size_hint_y: None
|
||||||
|
height: "120dp"
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
MDTextField:
|
||||||
from kivymd.uix.button import MDFlatButton
|
hint_text: "City"
|
||||||
from kivymd.uix.dialog import MDDialog
|
|
||||||
|
|
||||||
KV = '''
|
MDTextField:
|
||||||
<Content>
|
hint_text: "Street"
|
||||||
orientation: "vertical"
|
|
||||||
spacing: "12dp"
|
|
||||||
size_hint_y: None
|
|
||||||
height: "120dp"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "City"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Street"
|
|
||||||
|
|
||||||
|
|
||||||
MDFloatLayout:
|
MDFloatLayout:
|
||||||
|
|
||||||
MDFlatButton:
|
MDFlatButton:
|
||||||
text: "ALERT DIALOG"
|
text: "ALERT DIALOG"
|
||||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||||
on_release: app.show_confirmation_dialog()
|
on_release: app.show_confirmation_dialog()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Content(BoxLayout):
|
class Content(BoxLayout):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
dialog = None
|
dialog = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(KV)
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def show_confirmation_dialog(self):
|
def show_confirmation_dialog(self):
|
||||||
if not self.dialog:
|
if not self.dialog:
|
||||||
self.dialog = MDDialog(
|
self.dialog = MDDialog(
|
||||||
title="Address:",
|
title="Address:",
|
||||||
type="custom",
|
type="custom",
|
||||||
content_cls=Content(),
|
content_cls=Content(),
|
||||||
buttons=[
|
buttons=[
|
||||||
MDFlatButton(
|
MDFlatButton(
|
||||||
text="CANCEL",
|
text="CANCEL",
|
||||||
theme_text_color="Custom",
|
theme_text_color="Custom",
|
||||||
text_color=self.theme_cls.primary_color,
|
text_color=self.theme_cls.primary_color,
|
||||||
),
|
),
|
||||||
MDFlatButton(
|
MDFlatButton(
|
||||||
text="OK",
|
text="OK",
|
||||||
theme_text_color="Custom",
|
theme_text_color="Custom",
|
||||||
text_color=self.theme_cls.primary_color,
|
text_color=self.theme_cls.primary_color,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
self.dialog.open()
|
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
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dialog-custom.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -568,7 +460,7 @@ class MDDialog(BaseDialog):
|
||||||
|
|
||||||
md_bg_color = ColorProperty(None)
|
md_bg_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color in the (r, g, b, a) or string format.
|
Background color in the format (r, g, b, a).
|
||||||
|
|
||||||
:attr:`md_bg_color` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`md_bg_color` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<_Triangle>:
|
<_Triangle>:
|
||||||
canvas:
|
canvas:
|
||||||
Color:
|
Color:
|
||||||
rgba: app.theme_cls.text_color
|
rgba: root.theme_cls.text_color
|
||||||
Triangle:
|
Triangle:
|
||||||
points:
|
points:
|
||||||
[ \
|
[ \
|
||||||
|
@ -13,8 +13,7 @@
|
||||||
|
|
||||||
<MDDropDownItem>
|
<MDDropDownItem>
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
size_hint: None, None
|
adaptive_size: True
|
||||||
size: self.minimum_size
|
|
||||||
spacing: "5dp"
|
spacing: "5dp"
|
||||||
padding: "5dp", "5dp", "5dp", 0
|
padding: "5dp", "5dp", "5dp", 0
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,13 @@ Usage
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
MDScreen
|
Screen
|
||||||
|
|
||||||
MDDropDownItem:
|
MDDropDownItem:
|
||||||
id: drop_item
|
id: drop_item
|
||||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||||
text: 'Item'
|
text: 'Item'
|
||||||
on_release: print("Press item")
|
on_release: self.set_item("New Item")
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ import os
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.properties import NumericProperty, StringProperty
|
from kivy.properties import NumericProperty, StringProperty
|
||||||
from kivy.uix.behaviors import ButtonBehavior
|
from kivy.uix.behaviors import ButtonBehavior
|
||||||
from kivy.uix.boxlayout import BoxLayout
|
|
||||||
from kivy.uix.widget import Widget
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import DeclarativeBehavior
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.join(uix_path, "dropdownitem", "dropdownitem.kv"), encoding="utf-8"
|
os.path.join(uix_path, "dropdownitem", "dropdownitem.kv"), encoding="utf-8"
|
||||||
|
@ -61,12 +61,15 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class _Triangle(Widget):
|
class _Triangle(ThemableBehavior, Widget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MDDropDownItem(
|
class MDDropDownItem(
|
||||||
DeclarativeBehavior, ThemableBehavior, ButtonBehavior, BoxLayout
|
ThemableBehavior,
|
||||||
|
FakeRectangularElevationBehavior,
|
||||||
|
ButtonBehavior,
|
||||||
|
MDBoxLayout,
|
||||||
):
|
):
|
||||||
text = StringProperty()
|
text = StringProperty()
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -6,29 +6,28 @@
|
||||||
background_normal: ""
|
background_normal: ""
|
||||||
background_down: ""
|
background_down: ""
|
||||||
dir_or_file_name: ""
|
dir_or_file_name: ""
|
||||||
icon_color: 0, 0, 0, 0
|
|
||||||
_selected: False
|
_selected: False
|
||||||
events_callback: lambda x: None
|
events_callback: lambda x: None
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
|
|
||||||
ModifiedOneLineIconListItem:
|
ModifiedOneLineIconListItem:
|
||||||
text: root.dir_or_file_name
|
text: root.dir_or_file_name
|
||||||
on_release: root.events_callback(root.path, root)
|
|
||||||
bg_color:
|
bg_color:
|
||||||
self.theme_cls.bg_darkest \
|
self.theme_cls.bg_darkest \
|
||||||
if root._selected else \
|
if root._selected else self.theme_cls.bg_normal
|
||||||
self.theme_cls.bg_normal
|
on_release: root.events_callback(root.path, root)
|
||||||
|
|
||||||
IconLeftWidget:
|
IconLeftWidget:
|
||||||
icon: root.icon
|
icon: root.icon
|
||||||
theme_icon_color: "Custom"
|
theme_text_color: "Custom"
|
||||||
icon_color: root.icon_color
|
text_color: self.theme_cls.primary_color
|
||||||
|
|
||||||
MDSeparator:
|
MDSeparator:
|
||||||
|
|
||||||
|
|
||||||
<LabelContent@MDLabel>
|
<LabelContent@MDLabel>
|
||||||
adaptive_height: True
|
size_hint_y: None
|
||||||
|
height: self.texture_size[1]
|
||||||
shorten: True
|
shorten: True
|
||||||
shorten_from: "center"
|
shorten_from: "center"
|
||||||
halign: "center"
|
halign: "center"
|
||||||
|
@ -62,6 +61,23 @@
|
||||||
text: root.name
|
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>
|
<MDFileManager>
|
||||||
md_bg_color: root.theme_cls.bg_normal
|
md_bg_color: root.theme_cls.bg_normal
|
||||||
|
|
||||||
|
@ -74,11 +90,7 @@
|
||||||
title: root.current_path
|
title: root.current_path
|
||||||
right_action_items: [["close-box", lambda x: root.exit_manager(1)]]
|
right_action_items: [["close-box", lambda x: root.exit_manager(1)]]
|
||||||
left_action_items: [["chevron-left", lambda x: root.back()]]
|
left_action_items: [["chevron-left", lambda x: root.back()]]
|
||||||
elevation: 3
|
elevation: 10
|
||||||
md_bg_color:
|
|
||||||
app.theme_cls.primary_color \
|
|
||||||
if not root.background_color_toolbar else \
|
|
||||||
root.background_color_toolbar
|
|
||||||
|
|
||||||
RecycleView:
|
RecycleView:
|
||||||
id: rv
|
id: rv
|
||||||
|
|
|
@ -9,7 +9,7 @@ Usage
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
path = os.path.expanduser("~") # path to the directory that will be opened in the file manager
|
path = '/' # path to the directory that will be opened in the file manager
|
||||||
file_manager = MDFileManager(
|
file_manager = MDFileManager(
|
||||||
exit_manager=self.exit_manager, # function called when the user reaches directory tree root
|
exit_manager=self.exit_manager, # function called when the user reaches directory tree root
|
||||||
select_path=self.select_path, # function called when selecting a file/directory
|
select_path=self.select_path, # function called when selecting a file/directory
|
||||||
|
@ -19,7 +19,7 @@ Usage
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. warning:: Be careful! To use the `'/'` path on Android devices, you need
|
.. warning:: Be careful! To use the `/` path on Android devices, you need
|
||||||
special permissions. Therefore, you are likely to get an error.
|
special permissions. Therefore, you are likely to get an error.
|
||||||
|
|
||||||
Or with ``preview`` mode:
|
Or with ``preview`` mode:
|
||||||
|
@ -32,7 +32,7 @@ Or with ``preview`` mode:
|
||||||
preview=True,
|
preview=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-preview.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-previous.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. warning:: The `preview` mode is intended only for viewing images and will
|
.. warning:: The `preview` mode is intended only for viewing images and will
|
||||||
|
@ -43,8 +43,6 @@ Example
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
|
||||||
|
@ -55,19 +53,19 @@ Example
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
orientation: "vertical"
|
orientation: 'vertical'
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: "MDFileManager"
|
title: "MDFileManager"
|
||||||
left_action_items: [["menu", lambda x: None]]
|
left_action_items: [['menu', lambda x: None]]
|
||||||
elevation: 3
|
elevation: 10
|
||||||
|
|
||||||
MDFloatLayout:
|
MDFloatLayout:
|
||||||
|
|
||||||
MDRoundFlatIconButton:
|
MDRoundFlatIconButton:
|
||||||
text: "Open manager"
|
text: "Open manager"
|
||||||
icon: "folder"
|
icon: "folder"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {'center_x': .5, 'center_y': .6}
|
||||||
on_release: app.file_manager_open()
|
on_release: app.file_manager_open()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -78,23 +76,23 @@ Example
|
||||||
Window.bind(on_keyboard=self.events)
|
Window.bind(on_keyboard=self.events)
|
||||||
self.manager_open = False
|
self.manager_open = False
|
||||||
self.file_manager = MDFileManager(
|
self.file_manager = MDFileManager(
|
||||||
exit_manager=self.exit_manager, select_path=self.select_path
|
exit_manager=self.exit_manager,
|
||||||
|
select_path=self.select_path,
|
||||||
|
preview=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
def file_manager_open(self):
|
def file_manager_open(self):
|
||||||
self.file_manager.show(os.path.expanduser("~")) # output manager to the screen
|
self.file_manager.show('/') # output manager to the screen
|
||||||
self.manager_open = True
|
self.manager_open = True
|
||||||
|
|
||||||
def select_path(self, path: str):
|
def select_path(self, path):
|
||||||
'''
|
'''It will be called when you click on the file name
|
||||||
It will be called when you click on the file name
|
|
||||||
or the catalog selection button.
|
or the catalog selection button.
|
||||||
|
|
||||||
|
:type path: str;
|
||||||
:param path: path to the selected directory or file;
|
:param path: path to the selected directory or file;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -128,9 +126,6 @@ Not tested on `iOS`.
|
||||||
|
|
||||||
def file_manager_open(self):
|
def file_manager_open(self):
|
||||||
self.file_manager.show_disks()
|
self.file_manager.show_disks()
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-show-disks.png
|
|
||||||
:align: center
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ("MDFileManager",)
|
__all__ = ("MDFileManager",)
|
||||||
|
@ -141,7 +136,6 @@ import re
|
||||||
from typing import List, Tuple, Union
|
from typing import List, Tuple, Union
|
||||||
|
|
||||||
from kivy import platform
|
from kivy import platform
|
||||||
from kivy.clock import Clock
|
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.metrics import dp
|
from kivy.metrics import dp
|
||||||
|
@ -154,6 +148,7 @@ from kivy.properties import (
|
||||||
OptionProperty,
|
OptionProperty,
|
||||||
StringProperty,
|
StringProperty,
|
||||||
)
|
)
|
||||||
|
from kivy.uix.anchorlayout import AnchorLayout
|
||||||
from kivy.uix.behaviors import ButtonBehavior
|
from kivy.uix.behaviors import ButtonBehavior
|
||||||
from kivy.uix.modalview import ModalView
|
from kivy.uix.modalview import ModalView
|
||||||
|
|
||||||
|
@ -161,7 +156,6 @@ from kivymd import images_path, uix_path
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import CircularRippleBehavior
|
from kivymd.uix.behaviors import CircularRippleBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.button import MDFloatingActionButton
|
|
||||||
from kivymd.uix.fitimage import FitImage
|
from kivymd.uix.fitimage import FitImage
|
||||||
from kivymd.uix.list import BaseListItem
|
from kivymd.uix.list import BaseListItem
|
||||||
from kivymd.uix.relativelayout import MDRelativeLayout
|
from kivymd.uix.relativelayout import MDRelativeLayout
|
||||||
|
@ -173,7 +167,9 @@ with open(
|
||||||
|
|
||||||
|
|
||||||
class BodyManager(MDBoxLayout):
|
class BodyManager(MDBoxLayout):
|
||||||
"""Base class for folders and files icons."""
|
"""
|
||||||
|
Base class for folders and files icons.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class BodyManagerWithPreview(MDBoxLayout):
|
class BodyManagerWithPreview(MDBoxLayout):
|
||||||
|
@ -186,146 +182,47 @@ class IconButton(CircularRippleBehavior, ButtonBehavior, FitImage):
|
||||||
"""Folder icons/thumbnails images in ``preview`` mode."""
|
"""Folder icons/thumbnails images in ``preview`` mode."""
|
||||||
|
|
||||||
|
|
||||||
|
class FloatButton(ThemableBehavior, AnchorLayout):
|
||||||
|
callback = ObjectProperty()
|
||||||
|
md_bg_color = ColorProperty([1, 1, 1, 1])
|
||||||
|
icon = StringProperty()
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.theme_cls.bind(primary_palette=self.set_md_bg_color)
|
||||||
|
|
||||||
|
def set_md_bg_color(self, *args):
|
||||||
|
self.md_bg_color = self.theme_cls.primary_color
|
||||||
|
|
||||||
|
|
||||||
class ModifiedOneLineIconListItem(BaseListItem):
|
class ModifiedOneLineIconListItem(BaseListItem):
|
||||||
_txt_left_pad = NumericProperty("72dp")
|
_txt_left_pad = NumericProperty("72dp")
|
||||||
_txt_top_pad = NumericProperty("16dp")
|
_txt_top_pad = NumericProperty("16dp")
|
||||||
_txt_bot_pad = NumericProperty("15dp")
|
_txt_bot_pad = NumericProperty("15dp")
|
||||||
_num_lines = 1
|
_num_lines = 1
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
self.height = dp(48)
|
self.height = dp(48)
|
||||||
|
|
||||||
|
|
||||||
class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
class MDFileManager(ThemableBehavior, MDRelativeLayout):
|
||||||
|
icon = StringProperty("check")
|
||||||
"""
|
"""
|
||||||
Implements a modal dialog with a file manager.
|
The icon that will be used on the directory selection button.
|
||||||
|
|
||||||
For more information, see in the
|
|
||||||
:class:`~kivymd.uix.relativelayout.MDRelativeLayout` class documentation.
|
|
||||||
|
|
||||||
:Events:
|
|
||||||
`on_pre_open`:
|
|
||||||
Called before the MDFileManager is opened.
|
|
||||||
`on_open`:
|
|
||||||
Called when the MDFileManager is opened.
|
|
||||||
`on_pre_dismiss`:
|
|
||||||
Called before the MDFileManager is closed.
|
|
||||||
`on_dismiss`:
|
|
||||||
Called when the MDFileManager is closed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
icon = StringProperty("check", deprecated=True)
|
|
||||||
"""
|
|
||||||
Icon that will be used on the directory selection button.
|
|
||||||
|
|
||||||
.. deprecated:: 1.1.0
|
|
||||||
Use :attr:`icon_selection_button` instead.
|
|
||||||
|
|
||||||
:attr:`icon` is an :class:`~kivy.properties.StringProperty`
|
:attr:`icon` is an :class:`~kivy.properties.StringProperty`
|
||||||
and defaults to `check`.
|
and defaults to `check`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
icon_selection_button = StringProperty("check")
|
|
||||||
"""
|
|
||||||
Icon that will be used on the directory selection button.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDFileManager(
|
|
||||||
...
|
|
||||||
icon_selection_button="pencil",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-icon-selection-button.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`icon_selection_button` is an :class:`~kivy.properties.StringProperty`
|
|
||||||
and defaults to `check`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
background_color_selection_button = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
Background color of the current directory/path selection button.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDFileManager(
|
|
||||||
...
|
|
||||||
background_color_selection_button="brown",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-background-color-selection-button.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`background_color_selection_button` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
background_color_toolbar = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
Background color of the file manager toolbar.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDFileManager(
|
|
||||||
...
|
|
||||||
background_color_toolbar="brown",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-background-color-toolbar.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`background_color_toolbar` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
icon_folder = StringProperty(f"{images_path}folder.png")
|
icon_folder = StringProperty(f"{images_path}folder.png")
|
||||||
"""
|
"""
|
||||||
Icon that will be used for folder icons when using ``preview = True``.
|
The icon that will be used for folder icons when using ``preview = True``.
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDFileManager(
|
|
||||||
...
|
|
||||||
preview=True,
|
|
||||||
icon_folder="path/to/icon.png",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-icon-folder.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`icon` is an :class:`~kivy.properties.StringProperty`
|
:attr:`icon` is an :class:`~kivy.properties.StringProperty`
|
||||||
and defaults to `check`.
|
and defaults to `check`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
icon_color = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
Color of the folder icon when the :attr:`preview` property is set to False.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDFileManager(
|
|
||||||
...
|
|
||||||
preview=False,
|
|
||||||
icon_color="brown",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/file-manager-icon-color.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`icon_color` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
exit_manager = ObjectProperty(lambda x: None)
|
exit_manager = ObjectProperty(lambda x: None)
|
||||||
"""
|
"""
|
||||||
Function called when the user reaches directory tree root.
|
Function called when the user reaches directory tree root.
|
||||||
|
@ -362,12 +259,12 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
and defaults to `all`.
|
and defaults to `all`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
current_path = StringProperty(os.path.expanduser("~"))
|
current_path = StringProperty(os.getcwd())
|
||||||
"""
|
"""
|
||||||
Current directory.
|
Current directory.
|
||||||
|
|
||||||
:attr:`current_path` is an :class:`~kivy.properties.StringProperty`
|
:attr:`current_path` is an :class:`~kivy.properties.StringProperty`
|
||||||
and defaults to `os.path.expanduser("~")`.
|
and defaults to `/`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
use_access = BooleanProperty(True)
|
use_access = BooleanProperty(True)
|
||||||
|
@ -398,9 +295,9 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
"name", options=["nothing", "name", "date", "size", "type"]
|
"name", options=["nothing", "name", "date", "size", "type"]
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
It can take the values 'nothing' 'name' 'date' 'size' 'type' - sorts files
|
It can take the values 'nothing' 'name' 'date' 'size' 'type' - sorts files by option
|
||||||
by option. By default, sort by name. Available options are:
|
By default, sort by name.
|
||||||
`'nothing'`, `'name'`, `'date'`, `'size'`, `'type'`.
|
Available options are: `'nothing'`, `'name'`, `'date'`, `'size'`, `'type'`.
|
||||||
|
|
||||||
:attr:`sort_by` is an :class:`~kivy.properties.OptionProperty`
|
:attr:`sort_by` is an :class:`~kivy.properties.OptionProperty`
|
||||||
and defaults to `name`.
|
and defaults to `name`.
|
||||||
|
@ -428,33 +325,29 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
"""
|
"""
|
||||||
Contains the list of files that are currently selected.
|
Contains the list of files that are currently selected.
|
||||||
|
|
||||||
:attr:`selection` is a read-only :class:`~kivy.properties.ListProperty`
|
:attr:`selection` is a read-only :class:`~kivy.properties.ListProperty` and
|
||||||
and defaults to `[]`.
|
defaults to `[]`.
|
||||||
"""
|
|
||||||
|
|
||||||
selection_button = ObjectProperty()
|
|
||||||
"""
|
|
||||||
The instance of the directory/path selection button.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
:attr:`selection_button` is a read-only :class:`~kivy.properties.ObjectProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_window_manager = None
|
_window_manager = None
|
||||||
_window_manager_open = False
|
_window_manager_open = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
self.register_event_type("on_pre_open")
|
|
||||||
self.register_event_type("on_open")
|
|
||||||
self.register_event_type("on_pre_dismiss")
|
|
||||||
self.register_event_type("on_dismiss")
|
|
||||||
|
|
||||||
toolbar_label = self.ids.toolbar.children[1].children[0]
|
toolbar_label = self.ids.toolbar.children[1].children[0]
|
||||||
toolbar_label.font_style = "Subtitle1"
|
toolbar_label.font_style = "Subtitle1"
|
||||||
Clock.schedule_once(self._create_selection_button)
|
if (
|
||||||
|
self.selector == "any"
|
||||||
|
or self.selector == "multi"
|
||||||
|
or self.selector == "folder"
|
||||||
|
):
|
||||||
|
self.add_widget(
|
||||||
|
FloatButton(
|
||||||
|
callback=self.select_directory_on_press_button,
|
||||||
|
md_bg_color=self.theme_cls.primary_color,
|
||||||
|
icon=self.icon,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if self.preview:
|
if self.preview:
|
||||||
self.ext = [".png", ".jpg", ".jpeg"]
|
self.ext = [".png", ".jpg", ".jpeg"]
|
||||||
|
@ -507,7 +400,15 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.ids.rv.data = manager_list
|
self.ids.rv.data = manager_list
|
||||||
self._show()
|
|
||||||
|
if not self._window_manager:
|
||||||
|
self._window_manager = ModalView(
|
||||||
|
size_hint=self.size_hint, auto_dismiss=False
|
||||||
|
)
|
||||||
|
self._window_manager.add_widget(self)
|
||||||
|
if not self._window_manager_open:
|
||||||
|
self._window_manager.open()
|
||||||
|
self._window_manager_open = True
|
||||||
|
|
||||||
def show(self, path: str) -> None:
|
def show(self, path: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -573,9 +474,6 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
"icon": icon,
|
"icon": icon,
|
||||||
"dir_or_file_name": name,
|
"dir_or_file_name": name,
|
||||||
"events_callback": self.select_dir_or_file,
|
"events_callback": self.select_dir_or_file,
|
||||||
"icon_color": self.theme_cls.primary_color
|
|
||||||
if not self.icon_color
|
|
||||||
else self.icon_color,
|
|
||||||
"_selected": False,
|
"_selected": False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -590,14 +488,19 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
"icon": "file-outline",
|
"icon": "file-outline",
|
||||||
"dir_or_file_name": os.path.split(name)[1],
|
"dir_or_file_name": os.path.split(name)[1],
|
||||||
"events_callback": self.select_dir_or_file,
|
"events_callback": self.select_dir_or_file,
|
||||||
"icon_color": self.theme_cls.primary_color
|
|
||||||
if not self.icon_color
|
|
||||||
else self.icon_color,
|
|
||||||
"_selected": False,
|
"_selected": False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.ids.rv.data = manager_list
|
self.ids.rv.data = manager_list
|
||||||
self._show()
|
|
||||||
|
if not self._window_manager:
|
||||||
|
self._window_manager = ModalView(
|
||||||
|
size_hint=self.size_hint, auto_dismiss=False
|
||||||
|
)
|
||||||
|
self._window_manager.add_widget(self)
|
||||||
|
if not self._window_manager_open:
|
||||||
|
self._window_manager.open()
|
||||||
|
self._window_manager_open = True
|
||||||
|
|
||||||
def get_access_string(self, path: str) -> str:
|
def get_access_string(self, path: str) -> str:
|
||||||
access_string = ""
|
access_string = ""
|
||||||
|
@ -654,9 +557,7 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
"""Closes the file manager window."""
|
"""Closes the file manager window."""
|
||||||
|
|
||||||
self.dispatch("on_pre_dismiss")
|
|
||||||
self._window_manager.dismiss()
|
self._window_manager.dismiss()
|
||||||
self.dispatch("on_dismiss")
|
|
||||||
self._window_manager_open = False
|
self._window_manager_open = False
|
||||||
|
|
||||||
def select_dir_or_file(
|
def select_dir_or_file(
|
||||||
|
@ -708,84 +609,6 @@ class MDFileManager(MDRelativeLayout, ThemableBehavior):
|
||||||
if self.selector == "folder" or self.selector == "any":
|
if self.selector == "folder" or self.selector == "any":
|
||||||
self.select_path(self.current_path)
|
self.select_path(self.current_path)
|
||||||
|
|
||||||
def on_icon(self, instance_file_manager, icon_name: str) -> None:
|
|
||||||
"""Called when the :attr:`icon` property is changed."""
|
|
||||||
|
|
||||||
self.icon_selection_button = icon_name
|
|
||||||
|
|
||||||
def on_background_color_toolbar(
|
|
||||||
self, instance_file_manager, color: Union[str, list]
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Called when the :attr:`background_color_toolbar` property is changed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def on_background_color_toolbar(*args):
|
|
||||||
self.ids.toolbar.md_bg_color = color
|
|
||||||
|
|
||||||
Clock.schedule_once(on_background_color_toolbar)
|
|
||||||
|
|
||||||
def on_pre_open(self, *args):
|
|
||||||
"""
|
|
||||||
Default pre-open event handler.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
"""
|
|
||||||
|
|
||||||
def on_open(self, *args):
|
|
||||||
"""
|
|
||||||
Default open event handler.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
"""
|
|
||||||
|
|
||||||
def on_pre_dismiss(self, *args):
|
|
||||||
"""
|
|
||||||
Default pre-dismiss event handler.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
"""
|
|
||||||
|
|
||||||
def on_dismiss(self, *args):
|
|
||||||
"""
|
|
||||||
Default dismiss event handler.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _show(self):
|
|
||||||
if not self._window_manager:
|
|
||||||
self._window_manager = ModalView(
|
|
||||||
size_hint=self.size_hint, auto_dismiss=False
|
|
||||||
)
|
|
||||||
self.size_hint = (1, 1)
|
|
||||||
self._window_manager.add_widget(self)
|
|
||||||
|
|
||||||
if not self._window_manager_open:
|
|
||||||
self._window_manager.open()
|
|
||||||
self._window_manager_open = True
|
|
||||||
|
|
||||||
self.dispatch("on_pre_open")
|
|
||||||
self.dispatch("on_open")
|
|
||||||
|
|
||||||
def _create_selection_button(self, *args):
|
|
||||||
if (
|
|
||||||
self.selector == "any"
|
|
||||||
or self.selector == "multi"
|
|
||||||
or self.selector == "folder"
|
|
||||||
):
|
|
||||||
self.selection_button = MDFloatingActionButton(
|
|
||||||
on_release=self.select_directory_on_press_button,
|
|
||||||
md_bg_color=self.theme_cls.primary_color
|
|
||||||
if not self.background_color_selection_button
|
|
||||||
else self.background_color_selection_button,
|
|
||||||
icon=self.icon_selection_button,
|
|
||||||
pos_hint={"right": 0.99},
|
|
||||||
y=dp(12),
|
|
||||||
elevation=0,
|
|
||||||
)
|
|
||||||
self.add_widget(self.selection_button)
|
|
||||||
|
|
||||||
def __sort_files(self, files):
|
def __sort_files(self, files):
|
||||||
def sort_by_name(files):
|
def sort_by_name(files):
|
||||||
files.sort(key=locale.strxfrm)
|
files.sort(key=locale.strxfrm)
|
||||||
|
|
|
@ -132,11 +132,11 @@ from kivy.properties import BooleanProperty, ObjectProperty
|
||||||
from kivy.uix.image import AsyncImage
|
from kivy.uix.image import AsyncImage
|
||||||
from kivy.uix.widget import Widget
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
from kivymd.uix.behaviors import StencilBehavior
|
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
|
from kivymd.uix.templates import StencilWidget
|
||||||
|
|
||||||
|
|
||||||
class FitImage(MDBoxLayout, StencilBehavior):
|
class FitImage(MDBoxLayout, StencilWidget):
|
||||||
source = ObjectProperty()
|
source = ObjectProperty()
|
||||||
"""
|
"""
|
||||||
Filename/source of your image.
|
Filename/source of your image.
|
||||||
|
|
|
@ -90,7 +90,4 @@ from kivymd.uix.behaviors import DeclarativeBehavior
|
||||||
|
|
||||||
|
|
||||||
class MDGridLayout(DeclarativeBehavior, GridLayout, MDAdaptiveWidget):
|
class MDGridLayout(DeclarativeBehavior, GridLayout, MDAdaptiveWidget):
|
||||||
"""
|
pass
|
||||||
Grid layout class. For more information, see in the
|
|
||||||
:class:`~kivy.uix.gridlayout.GridLayout` class documentation.
|
|
||||||
"""
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ Base example
|
||||||
x: 24
|
x: 24
|
||||||
|
|
||||||
FitImage:
|
FitImage:
|
||||||
source: "kivymd/images/logo/kivymd-icon-512.png"
|
source: "https://github.com/kivymd/internal/raw/main/logo/kivymd_logo_blue.png"
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: hero_from.size
|
size: hero_from.size
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ Base example
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen B"
|
root.current = "screen B"
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
@ -82,7 +82,6 @@ Base example
|
||||||
|
|
||||||
MDHeroTo:
|
MDHeroTo:
|
||||||
id: hero_to
|
id: hero_to
|
||||||
tag: "hero"
|
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: "220dp", "220dp"
|
size: "220dp", "220dp"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
@ -92,7 +91,7 @@ Base example
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen A"
|
root.current = "screen A"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -114,7 +113,6 @@ Note that the child of the :class:`~MDHeroFrom` widget must have the size of the
|
||||||
|
|
||||||
MDHeroFrom:
|
MDHeroFrom:
|
||||||
id: hero_from
|
id: hero_from
|
||||||
tag: "hero"
|
|
||||||
|
|
||||||
FitImage:
|
FitImage:
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
|
@ -129,7 +127,7 @@ container in which the hero is located:
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
text: "Move Hero To Screen B"
|
text: "Move Hero To Screen B"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen 2"
|
root.current = "screen 2"
|
||||||
|
|
||||||
If you need to switch to a screen that does not contain heroes, set the
|
If you need to switch to a screen that does not contain heroes, set the
|
||||||
|
@ -140,7 +138,7 @@ If you need to switch to a screen that does not contain heroes, set the
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
text: "Go To Another Screen"
|
text: "Go To Another Screen"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = []
|
root.current_hero = ""
|
||||||
root.current = "another screen"
|
root.current = "another screen"
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
@ -168,7 +166,7 @@ Example
|
||||||
x: 24
|
x: 24
|
||||||
|
|
||||||
FitImage:
|
FitImage:
|
||||||
source: "kivymd/images/logo/kivymd-icon-512.png"
|
source: "https://github.com/kivymd/internal/raw/main/logo/kivymd_logo_blue.png"
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: hero_from.size
|
size: hero_from.size
|
||||||
|
|
||||||
|
@ -177,7 +175,7 @@ Example
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen B"
|
root.current = "screen B"
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
@ -187,7 +185,6 @@ Example
|
||||||
|
|
||||||
MDHeroTo:
|
MDHeroTo:
|
||||||
id: hero_to
|
id: hero_to
|
||||||
tag: "hero"
|
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: "220dp", "220dp"
|
size: "220dp", "220dp"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
@ -197,7 +194,7 @@ Example
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "52dp"
|
y: "52dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = []
|
root.current_hero = ""
|
||||||
root.current = "screen C"
|
root.current = "screen C"
|
||||||
|
|
||||||
MDRaisedButton:
|
MDRaisedButton:
|
||||||
|
@ -205,7 +202,7 @@ Example
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "8dp"
|
y: "8dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen A"
|
root.current = "screen A"
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
@ -286,7 +283,7 @@ background color of the hero during the flight between the screens:
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen B"
|
root.current = "screen B"
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
@ -296,7 +293,6 @@ background color of the hero during the flight between the screens:
|
||||||
|
|
||||||
MDHeroTo:
|
MDHeroTo:
|
||||||
id: hero_to
|
id: hero_to
|
||||||
tag: "hero"
|
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: "220dp", "220dp"
|
size: "220dp", "220dp"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
@ -306,7 +302,7 @@ background color of the hero during the flight between the screens:
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = ["hero"]
|
root.current_hero = "hero"
|
||||||
root.current = "screen A"
|
root.current = "screen A"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -374,7 +370,7 @@ Usage with ScrollView
|
||||||
radius: 24
|
radius: 24
|
||||||
box_radius: 0, 0, 24, 24
|
box_radius: 0, 0, 24, 24
|
||||||
box_color: 0, 0, 0, .5
|
box_color: 0, 0, 0, .5
|
||||||
source: "kivymd/images/logo/kivymd-icon-512.png"
|
source: "image.jpg"
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: root.size
|
size: root.size
|
||||||
mipmap: True
|
mipmap: True
|
||||||
|
@ -403,7 +399,7 @@ Usage with ScrollView
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
name: "screen B"
|
name: "screen B"
|
||||||
heroes_to: [hero_to]
|
hero_to: hero_to
|
||||||
|
|
||||||
MDHeroTo:
|
MDHeroTo:
|
||||||
id: hero_to
|
id: hero_to
|
||||||
|
@ -416,7 +412,7 @@ Usage with ScrollView
|
||||||
pos_hint: {"center_x": .5}
|
pos_hint: {"center_x": .5}
|
||||||
y: "36dp"
|
y: "36dp"
|
||||||
on_release:
|
on_release:
|
||||||
root.current_heroes = [hero_to.tag]
|
root.current_hero = "hero"
|
||||||
root.current = "screen A"
|
root.current = "screen A"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -445,8 +441,7 @@ Usage with ScrollView
|
||||||
|
|
||||||
def on_release(self):
|
def on_release(self):
|
||||||
def switch_screen(*args):
|
def switch_screen(*args):
|
||||||
self.manager.current_heroes = [self.tag]
|
self.manager.current_hero = self.tag
|
||||||
self.manager.ids.hero_to.tag = self.tag
|
|
||||||
self.manager.current = "screen B"
|
self.manager.current = "screen B"
|
||||||
|
|
||||||
Clock.schedule_once(switch_screen, 0.2)
|
Clock.schedule_once(switch_screen, 0.2)
|
||||||
|
@ -470,93 +465,6 @@ Usage with ScrollView
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/hero-usage-with-scrollview.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/hero-usage-with-scrollview.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Using multiple heroes at the same time
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivy.lang import Builder
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
KV = '''
|
|
||||||
MDScreenManager:
|
|
||||||
|
|
||||||
MDScreen:
|
|
||||||
name: "screen A"
|
|
||||||
md_bg_color: "lightblue"
|
|
||||||
|
|
||||||
MDHeroFrom:
|
|
||||||
id: hero_kivymd
|
|
||||||
tag: "kivymd"
|
|
||||||
size_hint: None, None
|
|
||||||
size: "200dp", "200dp"
|
|
||||||
pos_hint: {"top": .98}
|
|
||||||
x: 24
|
|
||||||
|
|
||||||
FitImage:
|
|
||||||
source: "kivymd/images/logo/kivymd-icon-512.png"
|
|
||||||
size_hint: None, None
|
|
||||||
size: hero_kivymd.size
|
|
||||||
|
|
||||||
MDHeroFrom:
|
|
||||||
id: hero_kivy
|
|
||||||
tag: "kivy"
|
|
||||||
size_hint: None, None
|
|
||||||
size: "200dp", "200dp"
|
|
||||||
pos_hint: {"top": .98}
|
|
||||||
x: 324
|
|
||||||
|
|
||||||
FitImage:
|
|
||||||
source: "data/logo/kivy-icon-512.png"
|
|
||||||
size_hint: None, None
|
|
||||||
size: hero_kivy.size
|
|
||||||
|
|
||||||
MDRaisedButton:
|
|
||||||
text: "Move Hero To Screen B"
|
|
||||||
pos_hint: {"center_x": .5}
|
|
||||||
y: "36dp"
|
|
||||||
on_release:
|
|
||||||
root.current_heroes = ["kivymd", "kivy"]
|
|
||||||
root.current = "screen B"
|
|
||||||
|
|
||||||
MDScreen:
|
|
||||||
name: "screen B"
|
|
||||||
heroes_to: hero_to_kivymd, hero_to_kivy
|
|
||||||
md_bg_color: "cadetblue"
|
|
||||||
|
|
||||||
MDHeroTo:
|
|
||||||
id: hero_to_kivy
|
|
||||||
tag: "kivy"
|
|
||||||
size_hint: None, None
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MDHeroTo:
|
|
||||||
id: hero_to_kivymd
|
|
||||||
tag: "kivymd"
|
|
||||||
size_hint: None, None
|
|
||||||
pos_hint: {"right": 1, "top": 1}
|
|
||||||
|
|
||||||
MDRaisedButton:
|
|
||||||
text: "Move Hero To Screen A"
|
|
||||||
pos_hint: {"center_x": .5}
|
|
||||||
y: "36dp"
|
|
||||||
on_release:
|
|
||||||
root.current_heroes = ["kivy", "kivymd"]
|
|
||||||
root.current = "screen A"
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
|
||||||
def build(self):
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/hero-multiple-heroes.gif
|
|
||||||
:align: center
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from kivy.properties import StringProperty
|
from kivy.properties import StringProperty
|
||||||
|
@ -568,9 +476,6 @@ class MDHeroFrom(MDBoxLayout):
|
||||||
"""
|
"""
|
||||||
The container from which the hero begins his flight.
|
The container from which the hero begins his flight.
|
||||||
|
|
||||||
For more information, see in the
|
|
||||||
:class:`~kivymd.uix.boxlayout.MDBoxLayout` class documentation.
|
|
||||||
|
|
||||||
:Events:
|
:Events:
|
||||||
`on_transform_in`
|
`on_transform_in`
|
||||||
when the hero flies from screen **A** to screen **B**.
|
when the hero flies from screen **A** to screen **B**.
|
||||||
|
@ -582,7 +487,7 @@ class MDHeroFrom(MDBoxLayout):
|
||||||
"""
|
"""
|
||||||
Tag ID for heroes.
|
Tag ID for heroes.
|
||||||
|
|
||||||
:attr:`tag` is an :class:`~kivy.properties.StringProperty`
|
:attr:`shift_right` is an :class:`~kivy.properties.StringProperty`
|
||||||
and defaults to `''`.
|
and defaults to `''`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -599,17 +504,4 @@ class MDHeroFrom(MDBoxLayout):
|
||||||
|
|
||||||
|
|
||||||
class MDHeroTo(MDBoxLayout):
|
class MDHeroTo(MDBoxLayout):
|
||||||
"""
|
"""The container in which the hero comes."""
|
||||||
The container in which the hero comes.
|
|
||||||
|
|
||||||
For more information, see in the
|
|
||||||
:class:`~kivymd.uix.boxlayout.MDBoxLayout` class documentation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
tag = StringProperty(allownone=True)
|
|
||||||
"""
|
|
||||||
Tag ID for heroes.
|
|
||||||
|
|
||||||
:attr:`tag` is an :class:`~kivy.properties.StringProperty`
|
|
||||||
and defaults to `''`.
|
|
||||||
"""
|
|
||||||
|
|
|
@ -65,13 +65,12 @@ Implementation
|
||||||
:align: center
|
:align: center
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = [
|
__all__ = "MDSmartTile"
|
||||||
"MDSmartTile",
|
|
||||||
]
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
from kivy.logger import Logger
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
|
|
|
@ -17,14 +17,8 @@
|
||||||
rgba: (1, 1, 1, 1) if self.source else (0, 0, 0, 0)
|
rgba: (1, 1, 1, 1) if self.source else (0, 0, 0, 0)
|
||||||
Rectangle:
|
Rectangle:
|
||||||
source: self.source if self.source else None
|
source: self.source if self.source else None
|
||||||
pos:
|
pos: self.pos
|
||||||
self.pos \
|
size: self.size
|
||||||
if not self.source else \
|
|
||||||
(self.x - self._size[0] / 2, self.y)
|
|
||||||
size:
|
|
||||||
self._size \
|
|
||||||
if self.source else \
|
|
||||||
self.size
|
|
||||||
|
|
||||||
font_style: "Icon"
|
font_style: "Icon"
|
||||||
text: u"{}".format(md_icons[root.icon]) if root.icon in md_icons else "blank"
|
text: u"{}".format(md_icons[root.icon]) if root.icon in md_icons else "blank"
|
||||||
|
|
|
@ -222,18 +222,14 @@ __all__ = ("MDLabel", "MDIcon")
|
||||||
import os
|
import os
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from kivy.animation import Animation
|
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.graphics import Color, Rectangle
|
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.metrics import sp
|
from kivy.metrics import sp
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
AliasProperty,
|
AliasProperty,
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
ListProperty,
|
|
||||||
NumericProperty,
|
NumericProperty,
|
||||||
ObjectProperty,
|
|
||||||
OptionProperty,
|
OptionProperty,
|
||||||
StringProperty,
|
StringProperty,
|
||||||
)
|
)
|
||||||
|
@ -326,7 +322,6 @@ class MDLabel(DeclarativeBehavior, ThemableBehavior, Label, MDAdaptiveWidget):
|
||||||
|
|
||||||
parent_background = ColorProperty(None)
|
parent_background = ColorProperty(None)
|
||||||
can_capitalize = BooleanProperty(True)
|
can_capitalize = BooleanProperty(True)
|
||||||
canvas_bg = ObjectProperty()
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
@ -354,7 +349,6 @@ class MDLabel(DeclarativeBehavior, ThemableBehavior, Label, MDAdaptiveWidget):
|
||||||
font_info = self.theme_cls.font_styles[self.font_style]
|
font_info = self.theme_cls.font_styles[self.font_style]
|
||||||
self.font_name = font_info[0]
|
self.font_name = font_info[0]
|
||||||
self.font_size = sp(font_info[1])
|
self.font_size = sp(font_info[1])
|
||||||
|
|
||||||
if font_info[2] and self.can_capitalize:
|
if font_info[2] and self.can_capitalize:
|
||||||
self._capitalizing = True
|
self._capitalizing = True
|
||||||
else:
|
else:
|
||||||
|
@ -380,68 +374,29 @@ class MDLabel(DeclarativeBehavior, ThemableBehavior, Label, MDAdaptiveWidget):
|
||||||
# generic None value it's not yet been set
|
# generic None value it's not yet been set
|
||||||
self._text_color_str = ""
|
self._text_color_str = ""
|
||||||
if theme_text_color == "Custom" and self.text_color:
|
if theme_text_color == "Custom" and self.text_color:
|
||||||
color = self.text_color
|
self.color = self.text_color
|
||||||
elif (
|
elif (
|
||||||
theme_text_color == "ContrastParentBackground"
|
theme_text_color == "ContrastParentBackground"
|
||||||
and self.parent_background
|
and self.parent_background
|
||||||
):
|
):
|
||||||
color = get_contrast_text_color(self.parent_background)
|
self.color = get_contrast_text_color(self.parent_background)
|
||||||
else:
|
else:
|
||||||
color = [0, 0, 0, 1]
|
self.color = [0, 0, 0, 1]
|
||||||
|
|
||||||
if self.theme_cls.theme_style_switch_animation:
|
def on_text_color(self, instance_label, color: list) -> None:
|
||||||
Animation(
|
|
||||||
color=color,
|
|
||||||
d=self.theme_cls.theme_style_switch_animation_duration,
|
|
||||||
t="linear",
|
|
||||||
).start(self)
|
|
||||||
else:
|
|
||||||
self.color = color
|
|
||||||
|
|
||||||
def on_text_color(self, instance_label, color: Union[list, str]) -> None:
|
|
||||||
if self.theme_text_color == "Custom":
|
if self.theme_text_color == "Custom":
|
||||||
if self.theme_cls.theme_style_switch_animation:
|
self.color = self.text_color
|
||||||
Animation(
|
|
||||||
color=self.text_color,
|
|
||||||
d=self.theme_cls.theme_style_switch_animation_duration,
|
|
||||||
t="linear",
|
|
||||||
).start(self)
|
|
||||||
else:
|
|
||||||
self.color = self.text_color
|
|
||||||
|
|
||||||
def on_opposite_colors(self, *args) -> None:
|
def on_opposite_colors(self, *args) -> None:
|
||||||
self.on_theme_text_color(self, self.theme_text_color)
|
self.on_theme_text_color(self, self.theme_text_color)
|
||||||
|
|
||||||
def on_md_bg_color(self, instance_label, color: Union[list, str]) -> None:
|
|
||||||
self.canvas.remove_group("Background_instruction")
|
|
||||||
with self.canvas.before:
|
|
||||||
Color(rgba=color)
|
|
||||||
self.canvas_bg = Rectangle(pos=self.pos, size=self.size)
|
|
||||||
self.bind(pos=self.update_canvas_bg_pos)
|
|
||||||
|
|
||||||
def on_size(self, instance_label, size: list) -> None:
|
|
||||||
if self.canvas_bg:
|
|
||||||
self.canvas_bg.size = size
|
|
||||||
|
|
||||||
def update_canvas_bg_pos(self, instance_label, pos: list) -> None:
|
|
||||||
if self.canvas_bg:
|
|
||||||
self.canvas_bg.pos = pos
|
|
||||||
|
|
||||||
def _do_update_theme_color(self, *args):
|
def _do_update_theme_color(self, *args):
|
||||||
if self._text_color_str:
|
if self._text_color_str:
|
||||||
|
self.color = getattr(self.theme_cls, self._text_color_str)
|
||||||
if not self.disabled:
|
if not self.disabled:
|
||||||
color = getattr(self.theme_cls, self._text_color_str)
|
self.color = getattr(self.theme_cls, self._text_color_str)
|
||||||
else:
|
else:
|
||||||
color = getattr(self.theme_cls, "disabled_hint_text_color")
|
self.color = getattr(self.theme_cls, "disabled_hint_text_color")
|
||||||
|
|
||||||
if self.theme_cls.theme_style_switch_animation:
|
|
||||||
Animation(
|
|
||||||
color=color,
|
|
||||||
d=self.theme_cls.theme_style_switch_animation_duration,
|
|
||||||
t="linear",
|
|
||||||
).start(self)
|
|
||||||
else:
|
|
||||||
self.color = color
|
|
||||||
|
|
||||||
|
|
||||||
class MDIcon(MDFloatLayout, MDLabel):
|
class MDIcon(MDFloatLayout, MDLabel):
|
||||||
|
@ -501,16 +456,11 @@ class MDIcon(MDFloatLayout, MDLabel):
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_size = ListProperty((0, 0))
|
def __init__(self, **kwargs):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
Clock.schedule_once(self.adjust_size)
|
|
||||||
|
|
||||||
def adjust_size(self, *args) -> None:
|
|
||||||
from kivymd.uix.selectioncontrol import MDCheckbox
|
from kivymd.uix.selectioncontrol import MDCheckbox
|
||||||
|
|
||||||
|
super().__init__(**kwargs)
|
||||||
if not isinstance(self, MDCheckbox):
|
if not isinstance(self, MDCheckbox):
|
||||||
self.size_hint = (None, None)
|
self.size_hint = (None, None)
|
||||||
self._size = self.texture_size[1], self.texture_size[1]
|
self.size = self.texture_size
|
||||||
self.adaptive_size = True
|
self.adaptive_size = True
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#:import STANDARD_INCREMENT kivymd.material_resources.STANDARD_INCREMENT
|
#:import STD_INC kivymd.material_resources.STANDARD_INCREMENT
|
||||||
|
|
||||||
|
|
||||||
<RightContent>
|
<RightContent>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
<MDMenu>
|
<MDMenu>
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
width: root.width_mult * STANDARD_INCREMENT
|
width: root.width_mult * STD_INC
|
||||||
bar_width: 0
|
bar_width: 0
|
||||||
key_viewclass: "viewclass"
|
key_viewclass: "viewclass"
|
||||||
key_size: "height"
|
key_size: "height"
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
|
|
||||||
|
|
||||||
<MenuContainer@MDCard>
|
<MenuContainer@MDCard+FakeRectangularElevationBehavior>
|
||||||
|
|
||||||
|
|
||||||
<MDDropdownMenu>
|
<MDDropdownMenu>
|
||||||
|
|
|
@ -781,7 +781,7 @@ class MDDropdownMenu(ThemableBehavior, FloatLayout):
|
||||||
and defaults to `'[dp(7)]'`.
|
and defaults to `'[dp(7)]'`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
elevation = NumericProperty(4)
|
elevation = NumericProperty(10)
|
||||||
"""
|
"""
|
||||||
Elevation value of menu dialog.
|
Elevation value of menu dialog.
|
||||||
|
|
||||||
|
@ -790,7 +790,7 @@ class MDDropdownMenu(ThemableBehavior, FloatLayout):
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
self.menu = MDDropdownMenu(
|
self.menu = MDDropdownMenu(
|
||||||
elevation=4,
|
elevation=16,
|
||||||
...,
|
...,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -798,7 +798,7 @@ class MDDropdownMenu(ThemableBehavior, FloatLayout):
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
||||||
and defaults to `4`.
|
and defaults to `10`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_start_coords = []
|
_start_coords = []
|
||||||
|
|
|
@ -61,7 +61,7 @@ A simple example
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: "Navigation Drawer"
|
title: "Navigation Drawer"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
md_bg_color: "#e7e4c0"
|
md_bg_color: "#e7e4c0"
|
||||||
specific_text_color: "#4a4939"
|
specific_text_color: "#4a4939"
|
||||||
|
@ -115,7 +115,7 @@ A simple example
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDTopAppBar(
|
MDTopAppBar(
|
||||||
title="Navigation Drawer",
|
title="Navigation Drawer",
|
||||||
elevation=4,
|
elevation=10,
|
||||||
pos_hint={"top": 1},
|
pos_hint={"top": 1},
|
||||||
md_bg_color="#e7e4c0",
|
md_bg_color="#e7e4c0",
|
||||||
specific_text_color="#4a4939",
|
specific_text_color="#4a4939",
|
||||||
|
@ -188,7 +188,7 @@ Standard content for the navigation bar
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: "Navigation Drawer"
|
title: "Navigation Drawer"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
md_bg_color: "#e7e4c0"
|
md_bg_color: "#e7e4c0"
|
||||||
specific_text_color: "#4a4939"
|
specific_text_color: "#4a4939"
|
||||||
|
@ -296,7 +296,7 @@ Standard content for the navigation bar
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDTopAppBar(
|
MDTopAppBar(
|
||||||
title="Navigation Drawer",
|
title="Navigation Drawer",
|
||||||
elevation=4,
|
elevation=10,
|
||||||
pos_hint={"top": 1},
|
pos_hint={"top": 1},
|
||||||
md_bg_color="#e7e4c0",
|
md_bg_color="#e7e4c0",
|
||||||
specific_text_color="#4a4939",
|
specific_text_color="#4a4939",
|
||||||
|
@ -396,7 +396,7 @@ Switching screens in the ``ScreenManager`` and using the common ``MDTopAppBar``
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
elevation: 4
|
elevation: 10
|
||||||
title: "MDNavigationDrawer"
|
title: "MDNavigationDrawer"
|
||||||
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
|
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ Switching screens in the ``ScreenManager`` and using the common ``MDTopAppBar``
|
||||||
MDScreen(
|
MDScreen(
|
||||||
MDTopAppBar(
|
MDTopAppBar(
|
||||||
pos_hint={"top": 1},
|
pos_hint={"top": 1},
|
||||||
elevation=4,
|
elevation=10,
|
||||||
title="MDNavigationDrawer",
|
title="MDNavigationDrawer",
|
||||||
left_action_items=[["menu", lambda x: self.nav_drawer_open()]],
|
left_action_items=[["menu", lambda x: self.nav_drawer_open()]],
|
||||||
),
|
),
|
||||||
|
@ -551,9 +551,14 @@ from kivy.properties import (
|
||||||
StringProperty,
|
StringProperty,
|
||||||
VariableListProperty,
|
VariableListProperty,
|
||||||
)
|
)
|
||||||
|
from kivy.uix.floatlayout import FloatLayout
|
||||||
from kivy.uix.screenmanager import ScreenManager
|
from kivy.uix.screenmanager import ScreenManager
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
from kivymd.uix.behaviors import (
|
||||||
|
DeclarativeBehavior,
|
||||||
|
FakeRectangularElevationBehavior,
|
||||||
|
)
|
||||||
from kivymd.uix.behaviors.focus_behavior import FocusBehavior
|
from kivymd.uix.behaviors.focus_behavior import FocusBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
@ -1024,7 +1029,7 @@ class MDNavigationDrawerMenu(MDScrollView):
|
||||||
widget.text_color = widget._text_color
|
widget.text_color = widget._text_color
|
||||||
|
|
||||||
|
|
||||||
class MDNavigationDrawer(MDCard):
|
class MDNavigationDrawer(MDCard, FakeRectangularElevationBehavior):
|
||||||
type = OptionProperty("modal", options=("standard", "modal"))
|
type = OptionProperty("modal", options=("standard", "modal"))
|
||||||
"""
|
"""
|
||||||
Type of drawer. Modal type will be on top of screen. Standard type will be
|
Type of drawer. Modal type will be on top of screen. Standard type will be
|
||||||
|
|
|
@ -29,86 +29,45 @@ Usage
|
||||||
|
|
||||||
MDNavigationRailItem:
|
MDNavigationRailItem:
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
from kivy.lang import Builder
|
KV = '''
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
KV = '''
|
|
||||||
MDBoxLayout:
|
|
||||||
|
|
||||||
MDNavigationRail:
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "Python"
|
|
||||||
icon: "language-python"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "JavaScript"
|
|
||||||
icon: "language-javascript"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "CPP"
|
|
||||||
icon: "language-cpp"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "Git"
|
|
||||||
icon: "git"
|
|
||||||
|
|
||||||
MDScreen:
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
MDBoxLayout:
|
||||||
def build(self):
|
|
||||||
return Builder.load_string(KV)
|
MDNavigationRail:
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "Python"
|
||||||
|
icon: "language-python"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "JavaScript"
|
||||||
|
icon: "language-javascript"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "CPP"
|
||||||
|
icon: "language-cpp"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "Git"
|
||||||
|
icon: "git"
|
||||||
|
|
||||||
|
MDScreen:
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
class Example(MDApp):
|
||||||
|
def build(self):
|
||||||
.. tab:: Declarative python style
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
|
||||||
from kivymd.uix.navigationrail import MDNavigationRail, MDNavigationRailItem
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
Example().run()
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return (
|
|
||||||
MDBoxLayout(
|
|
||||||
MDNavigationRail(
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="Python",
|
|
||||||
icon="language-python",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="JavaScript",
|
|
||||||
icon="language-javascript",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="CPP",
|
|
||||||
icon="language-cpp",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="Git",
|
|
||||||
icon="git",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/navigation-rail-usage.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/navigation-rail-usage.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -116,412 +75,202 @@ Usage
|
||||||
Example
|
Example
|
||||||
=======
|
=======
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV and imperative python styles
|
from kivy.clock import Clock
|
||||||
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
|
from kivymd.uix.button import MDFillRoundFlatIconButton
|
||||||
|
from kivymd.uix.label import MDLabel
|
||||||
|
from kivymd.uix.screen import MDScreen
|
||||||
|
|
||||||
from kivy.clock import Clock
|
KV = '''
|
||||||
from kivy.lang import Builder
|
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.behaviors import CommonElevationBehavior
|
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
|
||||||
from kivymd.uix.button import MDFillRoundFlatIconButton
|
|
||||||
from kivymd.uix.label import MDLabel
|
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
|
|
||||||
KV = '''
|
|
||||||
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
|
|
||||||
|
|
||||||
|
|
||||||
<ExtendedButton>
|
<ExtendedButton>
|
||||||
elevation: 3.5
|
elevation: 3
|
||||||
shadow_radius: 12
|
-height: "56dp"
|
||||||
shadow_softness: 4
|
|
||||||
-height: "56dp"
|
|
||||||
|
|
||||||
|
|
||||||
<DrawerClickableItem@MDNavigationDrawerItem>
|
<DrawerClickableItem@MDNavigationDrawerItem>
|
||||||
focus_color: "#e7e4c0"
|
focus_color: "#e7e4c0"
|
||||||
unfocus_color: "#fffcf4"
|
unfocus_color: "#fffcf4"
|
||||||
|
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
|
||||||
MDNavigationLayout:
|
MDNavigationLayout:
|
||||||
|
|
||||||
ScreenManager:
|
ScreenManager:
|
||||||
|
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
|
|
||||||
MDBoxLayout:
|
|
||||||
adaptive_height: True
|
|
||||||
md_bg_color: "#fffcf4"
|
|
||||||
padding: "12dp"
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
text: "12:00"
|
|
||||||
adaptive_height: True
|
|
||||||
pos_hint: {"center_y": .5}
|
|
||||||
|
|
||||||
MDBoxLayout:
|
|
||||||
|
|
||||||
MDNavigationRail:
|
|
||||||
id: navigation_rail
|
|
||||||
md_bg_color: "#fffcf4"
|
|
||||||
selected_color_background: "#e7e4c0"
|
|
||||||
ripple_color_item: "#e7e4c0"
|
|
||||||
on_item_release: app.switch_screen(*args)
|
|
||||||
|
|
||||||
MDNavigationRailMenuButton:
|
|
||||||
on_release: nav_drawer.set_state("open")
|
|
||||||
|
|
||||||
MDNavigationRailFabButton:
|
|
||||||
md_bg_color: "#b0f0d6"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "Python"
|
|
||||||
icon: "language-python"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "JavaScript"
|
|
||||||
icon: "language-javascript"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "CPP"
|
|
||||||
icon: "language-cpp"
|
|
||||||
|
|
||||||
MDNavigationRailItem:
|
|
||||||
text: "Swift"
|
|
||||||
icon: "language-swift"
|
|
||||||
|
|
||||||
ScreenManager:
|
|
||||||
id: screen_manager
|
|
||||||
transition:
|
|
||||||
FadeTransition(duration=.2, clearcolor=app.theme_cls.bg_dark)
|
|
||||||
|
|
||||||
MDNavigationDrawer:
|
|
||||||
id: nav_drawer
|
|
||||||
radius: (0, 16, 16, 0)
|
|
||||||
md_bg_color: "#fffcf4"
|
|
||||||
elevation: 4
|
|
||||||
width: "240dp"
|
|
||||||
|
|
||||||
MDNavigationDrawerMenu:
|
|
||||||
|
|
||||||
MDBoxLayout:
|
MDBoxLayout:
|
||||||
orientation: "vertical"
|
|
||||||
adaptive_height: True
|
adaptive_height: True
|
||||||
spacing: "12dp"
|
md_bg_color: "#fffcf4"
|
||||||
padding: "3dp", 0, 0, "12dp"
|
padding: "12dp"
|
||||||
|
|
||||||
MDIconButton:
|
MDLabel:
|
||||||
icon: "menu"
|
text: "12:00"
|
||||||
|
adaptive_height: True
|
||||||
|
pos_hint: {"center_y": .5}
|
||||||
|
|
||||||
ExtendedButton:
|
MDBoxLayout:
|
||||||
text: "Compose"
|
|
||||||
icon: "pencil"
|
|
||||||
|
|
||||||
DrawerClickableItem:
|
MDNavigationRail:
|
||||||
text: "Python"
|
id: navigation_rail
|
||||||
icon: "language-python"
|
md_bg_color: "#fffcf4"
|
||||||
|
selected_color_background: "#e7e4c0"
|
||||||
|
ripple_color_item: "#e7e4c0"
|
||||||
|
on_item_release: app.switch_screen(*args)
|
||||||
|
|
||||||
DrawerClickableItem:
|
MDNavigationRailMenuButton:
|
||||||
text: "JavaScript"
|
on_release: nav_drawer.set_state("open")
|
||||||
icon: "language-javascript"
|
|
||||||
|
|
||||||
DrawerClickableItem:
|
MDNavigationRailFabButton:
|
||||||
text: "CPP"
|
md_bg_color: "#b0f0d6"
|
||||||
icon: "language-cpp"
|
|
||||||
|
|
||||||
DrawerClickableItem:
|
MDNavigationRailItem:
|
||||||
text: "Swift"
|
text: "Python"
|
||||||
icon: "language-swift"
|
icon: "language-python"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "JavaScript"
|
||||||
|
icon: "language-javascript"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "CPP"
|
||||||
|
icon: "language-cpp"
|
||||||
|
|
||||||
|
MDNavigationRailItem:
|
||||||
|
text: "Swift"
|
||||||
|
icon: "language-swift"
|
||||||
|
|
||||||
|
ScreenManager:
|
||||||
|
id: screen_manager
|
||||||
|
transition:
|
||||||
|
FadeTransition(duration=.2, clearcolor=app.theme_cls.bg_dark)
|
||||||
|
|
||||||
|
MDNavigationDrawer:
|
||||||
|
id: nav_drawer
|
||||||
|
radius: (0, 16, 16, 0)
|
||||||
|
md_bg_color: "#fffcf4"
|
||||||
|
elevation: 12
|
||||||
|
width: "240dp"
|
||||||
|
|
||||||
|
MDNavigationDrawerMenu:
|
||||||
|
|
||||||
|
MDBoxLayout:
|
||||||
|
orientation: "vertical"
|
||||||
|
adaptive_height: True
|
||||||
|
spacing: "12dp"
|
||||||
|
padding: 0, 0, 0, "12dp"
|
||||||
|
|
||||||
|
MDIconButton:
|
||||||
|
icon: "menu"
|
||||||
|
|
||||||
|
ExtendedButton:
|
||||||
|
text: "Compose"
|
||||||
|
icon: "pencil"
|
||||||
|
|
||||||
|
DrawerClickableItem:
|
||||||
|
text: "Python"
|
||||||
|
icon: "language-python"
|
||||||
|
|
||||||
|
DrawerClickableItem:
|
||||||
|
text: "JavaScript"
|
||||||
|
icon: "language-javascript"
|
||||||
|
|
||||||
|
DrawerClickableItem:
|
||||||
|
text: "CPP"
|
||||||
|
icon: "language-cpp"
|
||||||
|
|
||||||
|
DrawerClickableItem:
|
||||||
|
text: "Swift"
|
||||||
|
icon: "language-swift"
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendedButton(
|
||||||
|
RoundedRectangularElevationBehavior, MDFillRoundFlatIconButton
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
Implements a button of type
|
||||||
|
`Extended FAB <https://m3.material.io/components/extended-fab/overview>`_.
|
||||||
|
|
||||||
|
.. rubric::
|
||||||
|
Extended FABs help people take primary actions.
|
||||||
|
They're wider than FABs to accommodate a text label and larger target
|
||||||
|
area.
|
||||||
|
|
||||||
|
This type of buttons is not yet implemented in the standard widget set
|
||||||
|
of the KivyMD library, so we will implement it ourselves in this class.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.padding = "16dp"
|
||||||
|
Clock.schedule_once(self.set_spacing)
|
||||||
|
|
||||||
|
def set_spacing(self, interval):
|
||||||
|
self.ids.box.spacing = "12dp"
|
||||||
|
|
||||||
|
def set_radius(self, *args):
|
||||||
|
if self.rounded_button:
|
||||||
|
self._radius = self.radius = self.height / 4
|
||||||
|
|
||||||
|
|
||||||
|
class Example(MDApp):
|
||||||
|
def build(self):
|
||||||
|
self.theme_cls.material_style = "M3"
|
||||||
|
self.theme_cls.primary_palette = "Orange"
|
||||||
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
|
def switch_screen(
|
||||||
|
self, instance_navigation_rail, instance_navigation_rail_item
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
Called when tapping on rail menu items. Switches application screens.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
self.root.ids.screen_manager.current = (
|
||||||
class ExtendedButton(MDFillRoundFlatIconButton, CommonElevationBehavior):
|
instance_navigation_rail_item.icon.split("-")[1].lower()
|
||||||
'''
|
|
||||||
Implements a button of type
|
|
||||||
`Extended FAB <https://m3.material.io/components/extended-fab/overview>`_.
|
|
||||||
|
|
||||||
.. rubric::
|
|
||||||
Extended FABs help people take primary actions.
|
|
||||||
They're wider than FABs to accommodate a text label and larger target
|
|
||||||
area.
|
|
||||||
|
|
||||||
This type of buttons is not yet implemented in the standard widget set
|
|
||||||
of the KivyMD library, so we will implement it ourselves in this class.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.padding = "16dp"
|
|
||||||
Clock.schedule_once(self.set_spacing)
|
|
||||||
|
|
||||||
def set_spacing(self, interval):
|
|
||||||
self.ids.box.spacing = "12dp"
|
|
||||||
|
|
||||||
def set_radius(self, *args):
|
|
||||||
if self.rounded_button:
|
|
||||||
self._radius = self.radius = self.height / 4
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.material_style = "M3"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def switch_screen(
|
|
||||||
self, instance_navigation_rail, instance_navigation_rail_item
|
|
||||||
):
|
|
||||||
'''
|
|
||||||
Called when tapping on rail menu items. Switches application screens.
|
|
||||||
'''
|
|
||||||
|
|
||||||
self.root.ids.screen_manager.current = (
|
|
||||||
instance_navigation_rail_item.icon.split("-")[1].lower()
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_start(self):
|
|
||||||
'''Creates application screens.'''
|
|
||||||
|
|
||||||
navigation_rail_items = self.root.ids.navigation_rail.get_items()[:]
|
|
||||||
navigation_rail_items.reverse()
|
|
||||||
|
|
||||||
for widget in navigation_rail_items:
|
|
||||||
name_screen = widget.icon.split("-")[1].lower()
|
|
||||||
screen = MDScreen(
|
|
||||||
name=name_screen,
|
|
||||||
md_bg_color="#edd769",
|
|
||||||
radius=[18, 0, 0, 0],
|
|
||||||
)
|
|
||||||
box = MDBoxLayout(padding="12dp")
|
|
||||||
label = MDLabel(
|
|
||||||
text=name_screen.capitalize(),
|
|
||||||
font_style="H1",
|
|
||||||
halign="right",
|
|
||||||
adaptive_height=True,
|
|
||||||
shorten=True,
|
|
||||||
)
|
|
||||||
box.add_widget(label)
|
|
||||||
screen.add_widget(box)
|
|
||||||
self.root.ids.screen_manager.add_widget(screen)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivy.clock import Clock
|
|
||||||
from kivy.metrics import dp
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.behaviors import CommonElevationBehavior
|
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
|
||||||
from kivymd.uix.button import MDFillRoundFlatIconButton, MDIconButton
|
|
||||||
from kivymd.uix.label import MDLabel
|
|
||||||
from kivymd.uix.navigationdrawer import (
|
|
||||||
MDNavigationDrawerItem,
|
|
||||||
MDNavigationLayout,
|
|
||||||
MDNavigationDrawer,
|
|
||||||
MDNavigationDrawerMenu,
|
|
||||||
)
|
)
|
||||||
from kivymd.uix.navigationrail import (
|
|
||||||
MDNavigationRail,
|
def on_start(self):
|
||||||
MDNavigationRailMenuButton,
|
'''Creates application screens.'''
|
||||||
MDNavigationRailFabButton,
|
|
||||||
MDNavigationRailItem,
|
navigation_rail_items = self.root.ids.navigation_rail.get_items()[:]
|
||||||
)
|
navigation_rail_items.reverse()
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
from kivymd.uix.screenmanager import MDScreenManager
|
for widget in navigation_rail_items:
|
||||||
|
name_screen = widget.icon.split("-")[1].lower()
|
||||||
|
screen = MDScreen(
|
||||||
|
name=name_screen,
|
||||||
|
md_bg_color="#edd769",
|
||||||
|
radius=[18, 0, 0, 0],
|
||||||
|
)
|
||||||
|
box = MDBoxLayout(padding="12dp")
|
||||||
|
label = MDLabel(
|
||||||
|
text=name_screen.capitalize(),
|
||||||
|
font_style="H1",
|
||||||
|
halign="right",
|
||||||
|
adaptive_height=True,
|
||||||
|
shorten=True,
|
||||||
|
)
|
||||||
|
box.add_widget(label)
|
||||||
|
screen.add_widget(box)
|
||||||
|
self.root.ids.screen_manager.add_widget(screen)
|
||||||
|
|
||||||
|
|
||||||
class DrawerClickableItem(MDNavigationDrawerItem):
|
Example().run()
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.focus_color = "#e7e4c0"
|
|
||||||
self.unfocus_color = self.theme_cls.bg_light
|
|
||||||
self.radius = 24
|
|
||||||
|
|
||||||
|
|
||||||
class ExtendedButton(MDFillRoundFlatIconButton, CommonElevationBehavior):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.padding = "16dp"
|
|
||||||
self.elevation = 3.5
|
|
||||||
self.shadow_radius = 12
|
|
||||||
self.shadow_softness = 4
|
|
||||||
self.height = dp(56)
|
|
||||||
Clock.schedule_once(self.set_spacing)
|
|
||||||
|
|
||||||
def set_spacing(self, interval):
|
|
||||||
self.ids.box.spacing = "12dp"
|
|
||||||
|
|
||||||
def set_radius(self, *args):
|
|
||||||
if self.rounded_button:
|
|
||||||
self._radius = self.radius = self.height / 4
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.material_style = "M3"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return MDScreen(
|
|
||||||
MDNavigationLayout(
|
|
||||||
MDScreenManager(
|
|
||||||
MDScreen(
|
|
||||||
MDBoxLayout(
|
|
||||||
MDBoxLayout(
|
|
||||||
MDLabel(
|
|
||||||
text="12:00",
|
|
||||||
adaptive_height=True,
|
|
||||||
pos_hint={"center_y": 0.5},
|
|
||||||
),
|
|
||||||
adaptive_height=True,
|
|
||||||
md_bg_color="#fffcf4",
|
|
||||||
padding="12dp",
|
|
||||||
),
|
|
||||||
MDBoxLayout(
|
|
||||||
MDNavigationRail(
|
|
||||||
MDNavigationRailMenuButton(
|
|
||||||
on_release=self.open_nav_drawer,
|
|
||||||
),
|
|
||||||
MDNavigationRailFabButton(
|
|
||||||
md_bg_color="#b0f0d6",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="Python",
|
|
||||||
icon="language-python",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="JavaScript",
|
|
||||||
icon="language-javascript",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="CPP",
|
|
||||||
icon="language-cpp",
|
|
||||||
),
|
|
||||||
MDNavigationRailItem(
|
|
||||||
text="Swift",
|
|
||||||
icon="language-swift",
|
|
||||||
),
|
|
||||||
id="navigation_rail",
|
|
||||||
md_bg_color="#fffcf4",
|
|
||||||
selected_color_background="#e7e4c0",
|
|
||||||
ripple_color_item="#e7e4c0",
|
|
||||||
),
|
|
||||||
MDScreenManager(
|
|
||||||
id="screen_manager_content",
|
|
||||||
),
|
|
||||||
id="root_box",
|
|
||||||
),
|
|
||||||
id="box_rail",
|
|
||||||
orientation="vertical",
|
|
||||||
),
|
|
||||||
id="box",
|
|
||||||
),
|
|
||||||
id="screen",
|
|
||||||
),
|
|
||||||
id="screen_manager",
|
|
||||||
),
|
|
||||||
MDNavigationDrawer(
|
|
||||||
MDNavigationDrawerMenu(
|
|
||||||
MDBoxLayout(
|
|
||||||
MDIconButton(
|
|
||||||
icon="menu",
|
|
||||||
),
|
|
||||||
ExtendedButton(
|
|
||||||
text="Compose",
|
|
||||||
icon="pencil",
|
|
||||||
),
|
|
||||||
orientation="vertical",
|
|
||||||
adaptive_height=True,
|
|
||||||
spacing="12dp",
|
|
||||||
padding=("3dp", 0, 0, "12dp"),
|
|
||||||
),
|
|
||||||
DrawerClickableItem(
|
|
||||||
text="Python",
|
|
||||||
icon="language-python",
|
|
||||||
),
|
|
||||||
DrawerClickableItem(
|
|
||||||
text="JavaScript",
|
|
||||||
icon="language-javascript",
|
|
||||||
),
|
|
||||||
DrawerClickableItem(
|
|
||||||
text="CPP",
|
|
||||||
icon="language-cpp",
|
|
||||||
),
|
|
||||||
DrawerClickableItem(
|
|
||||||
text="Swift",
|
|
||||||
icon="language-swift",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
id="nav_drawer",
|
|
||||||
radius=(0, 16, 16, 0),
|
|
||||||
elevation=4,
|
|
||||||
width="240dp",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
def switch_screen(self, *args, screen_manager_content=None):
|
|
||||||
'''
|
|
||||||
Called when tapping on rail menu items. Switches application screens.
|
|
||||||
'''
|
|
||||||
|
|
||||||
instance_navigation_rail, instance_navigation_rail_item = args
|
|
||||||
screen_manager_content.current = (
|
|
||||||
instance_navigation_rail_item.icon.split("-")[1].lower()
|
|
||||||
)
|
|
||||||
|
|
||||||
def open_nav_drawer(self, *args):
|
|
||||||
self.root.ids.nav_drawer.set_state("open")
|
|
||||||
|
|
||||||
def on_start(self):
|
|
||||||
'''Creates application screens.'''
|
|
||||||
|
|
||||||
screen_manager = self.root.ids.screen_manager
|
|
||||||
root_box = screen_manager.ids.screen.ids.box.ids.box_rail.ids.root_box
|
|
||||||
navigation_rail = root_box.ids.navigation_rail
|
|
||||||
screen_manager_content = root_box.ids.screen_manager_content
|
|
||||||
navigation_rail_items = navigation_rail.get_items()[:]
|
|
||||||
navigation_rail_items.reverse()
|
|
||||||
navigation_rail.bind(
|
|
||||||
on_item_release=lambda *args: self.switch_screen(
|
|
||||||
*args, screen_manager_content=screen_manager_content
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
for widget in navigation_rail_items:
|
|
||||||
name_screen = widget.icon.split("-")[1].lower()
|
|
||||||
screen_manager_content.add_widget(
|
|
||||||
MDScreen(
|
|
||||||
MDBoxLayout(
|
|
||||||
MDLabel(
|
|
||||||
text=name_screen.capitalize(),
|
|
||||||
font_style="H1",
|
|
||||||
halign="right",
|
|
||||||
adaptive_height=True,
|
|
||||||
shorten=True,
|
|
||||||
),
|
|
||||||
padding="12dp",
|
|
||||||
),
|
|
||||||
name=name_screen,
|
|
||||||
md_bg_color="#edd769",
|
|
||||||
radius=[18, 0, 0, 0],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/navigation-rail-example.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/navigation-rail-example.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -557,11 +306,12 @@ from kivy.uix.behaviors import ButtonBehavior
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import ScaleBehavior
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.button import MDFloatingActionButton, MDIconButton
|
from kivymd.uix.button import MDFloatingActionButton, MDIconButton
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
from kivymd.uix.floatlayout import MDFloatLayout
|
from kivymd.uix.floatlayout import MDFloatLayout
|
||||||
|
from kivymd.uix.templates import ScaleWidget
|
||||||
from kivymd.uix.widget import MDWidget
|
from kivymd.uix.widget import MDWidget
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
|
@ -583,7 +333,7 @@ class PanelItems(MDBoxLayout):
|
||||||
"""Box for menu items."""
|
"""Box for menu items."""
|
||||||
|
|
||||||
|
|
||||||
class RippleWidget(MDWidget, ScaleBehavior):
|
class RippleWidget(MDWidget, ScaleWidget):
|
||||||
"""
|
"""
|
||||||
Implements a background color for a menu item -
|
Implements a background color for a menu item -
|
||||||
(:class:`~MDNavigationRailItem`).
|
(:class:`~MDNavigationRailItem`).
|
||||||
|
@ -812,7 +562,7 @@ class MDNavigationRailItem(ThemableBehavior, ButtonBehavior, MDBoxLayout):
|
||||||
self.navigation_rail.dispatch("on_item_release", self)
|
self.navigation_rail.dispatch("on_item_release", self)
|
||||||
|
|
||||||
|
|
||||||
class MDNavigationRail(MDCard):
|
class MDNavigationRail(MDCard, FakeRectangularElevationBehavior):
|
||||||
"""
|
"""
|
||||||
:Events:
|
:Events:
|
||||||
:attr:`on_item_press`
|
:attr:`on_item_press`
|
||||||
|
|
|
@ -11,110 +11,65 @@ Components/DatePicker
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/picker-previous.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/picker-previous.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
|
.. warning:: The widget is under testing. Therefore, we would be grateful if
|
||||||
|
you would let us know about the bugs found.
|
||||||
|
|
||||||
.. rubric:: Usage
|
.. rubric:: Usage
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.pickers import MDDatePicker
|
||||||
|
|
||||||
from kivy.lang import Builder
|
KV = '''
|
||||||
|
MDFloatLayout:
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
MDTopAppBar:
|
||||||
from kivymd.uix.pickers import MDDatePicker
|
title: "MDDatePicker"
|
||||||
|
pos_hint: {"top": 1}
|
||||||
|
elevation: 10
|
||||||
|
|
||||||
KV = '''
|
MDRaisedButton:
|
||||||
MDFloatLayout:
|
text: "Open date picker"
|
||||||
|
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||||
|
on_release: app.show_date_picker()
|
||||||
|
'''
|
||||||
|
|
||||||
MDRaisedButton:
|
|
||||||
text: "Open date picker"
|
class Test(MDApp):
|
||||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
def build(self):
|
||||||
on_release: app.show_date_picker()
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
|
def on_save(self, instance, value, date_range):
|
||||||
|
'''
|
||||||
|
Events called when the "OK" dialog box button is clicked.
|
||||||
|
|
||||||
|
:type instance: <kivymd.uix.picker.MDDatePicker object>;
|
||||||
|
|
||||||
|
:param value: selected date;
|
||||||
|
:type value: <class 'datetime.date'>;
|
||||||
|
|
||||||
|
:param date_range: list of 'datetime.date' objects in the selected range;
|
||||||
|
:type date_range: <class 'list'>;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
print(instance, value, date_range)
|
||||||
|
|
||||||
class Test(MDApp):
|
def on_cancel(self, instance, value):
|
||||||
def build(self):
|
'''Events called when the "CANCEL" dialog box button is clicked.'''
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def on_save(self, instance, value, date_range):
|
def show_date_picker(self):
|
||||||
'''
|
date_dialog = MDDatePicker()
|
||||||
Events called when the "OK" dialog box button is clicked.
|
date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel)
|
||||||
|
date_dialog.open()
|
||||||
:type instance: <kivymd.uix.picker.MDDatePicker object>;
|
|
||||||
:param value: selected date;
|
|
||||||
:type value: <class 'datetime.date'>;
|
|
||||||
:param date_range: list of 'datetime.date' objects in the selected range;
|
|
||||||
:type date_range: <class 'list'>;
|
|
||||||
'''
|
|
||||||
|
|
||||||
print(instance, value, date_range)
|
|
||||||
|
|
||||||
def on_cancel(self, instance, value):
|
|
||||||
'''Events called when the "CANCEL" dialog box button is clicked.'''
|
|
||||||
|
|
||||||
def show_date_picker(self):
|
|
||||||
date_dialog = MDDatePicker()
|
|
||||||
date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel)
|
|
||||||
date_dialog.open()
|
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
Test().run()
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.button import MDRaisedButton
|
|
||||||
from kivymd.uix.pickers import MDDatePicker
|
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/MDDatePicker.gif
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return (
|
|
||||||
MDScreen(
|
|
||||||
MDRaisedButton(
|
|
||||||
text="Open data picker",
|
|
||||||
pos_hint={'center_x': .5, 'center_y': .5},
|
|
||||||
on_release=self.show_date_picker,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_save(self, instance, value, date_range):
|
|
||||||
'''
|
|
||||||
Events called when the "OK" dialog box button is clicked.
|
|
||||||
|
|
||||||
:type instance: <kivymd.uix.picker.MDDatePicker object>;
|
|
||||||
|
|
||||||
:param value: selected date;
|
|
||||||
:type value: <class 'datetime.date'>;
|
|
||||||
|
|
||||||
:param date_range: list of 'datetime.date' objects in the selected range;
|
|
||||||
:type date_range: <class 'list'>;
|
|
||||||
'''
|
|
||||||
|
|
||||||
print(instance, value, date_range)
|
|
||||||
|
|
||||||
def on_cancel(self, instance, value):
|
|
||||||
'''Events called when the "CANCEL" dialog box button is clicked.'''
|
|
||||||
|
|
||||||
def show_date_picker(self, *args):
|
|
||||||
date_dialog = MDDatePicker()
|
|
||||||
date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel)
|
|
||||||
date_dialog.open()
|
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/MDDatePicker.png
|
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Open date dialog with the specified date
|
Open date dialog with the specified date
|
||||||
|
@ -126,7 +81,7 @@ Open date dialog with the specified date
|
||||||
date_dialog = MDDatePicker(year=1983, month=4, day=12)
|
date_dialog = MDDatePicker(year=1983, month=4, day=12)
|
||||||
date_dialog.open()
|
date_dialog.open()
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/specified-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/previous-date.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Interval date
|
Interval date
|
||||||
|
@ -139,16 +94,12 @@ that are not included in this range will have the status `disabled`.
|
||||||
|
|
||||||
def show_date_picker(self):
|
def show_date_picker(self):
|
||||||
date_dialog = MDDatePicker(
|
date_dialog = MDDatePicker(
|
||||||
min_date=datetime.date.today(),
|
min_date=datetime.date(2021, 2, 15),
|
||||||
max_date=datetime.date(
|
max_date=datetime.date(2021, 3, 27),
|
||||||
datetime.date.today().year,
|
|
||||||
datetime.date.today().month,
|
|
||||||
datetime.date.today().day + 2,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
date_dialog.open()
|
date_dialog.open()
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/range-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/range-date.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
The range of available dates can be changed in the picker dialog:
|
The range of available dates can be changed in the picker dialog:
|
||||||
|
@ -171,7 +122,7 @@ You can set the range of years using the :attr:`~kivymd.uix.picker.MDDatePicker.
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def show_date_picker(self):
|
def show_date_picker(self):
|
||||||
date_dialog = MDDatePicker(min_year=2022, max_year=2030)
|
date_dialog = MDDatePicker(min_year=2021, max_year=2030)
|
||||||
date_dialog.open()
|
date_dialog.open()
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/min-max-year-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/min-max-year-date.png
|
||||||
|
@ -190,8 +141,6 @@ Set and select a date range
|
||||||
:align: center
|
:align: center
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
__all__ = ("MDDatePicker", "BaseDialogPicker", "DatePickerInputField")
|
__all__ = ("MDDatePicker", "BaseDialogPicker", "DatePickerInputField")
|
||||||
|
|
||||||
import calendar
|
import calendar
|
||||||
|
@ -203,6 +152,7 @@ from typing import Union
|
||||||
|
|
||||||
from kivy import Logger
|
from kivy import Logger
|
||||||
from kivy.animation import Animation
|
from kivy.animation import Animation
|
||||||
|
from kivy.clock import Clock
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.metrics import dp
|
from kivy.metrics import dp
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
|
@ -225,7 +175,7 @@ from kivymd.theming import ThemableBehavior, ThemeManager
|
||||||
from kivymd.toast import toast
|
from kivymd.toast import toast
|
||||||
from kivymd.uix.behaviors import (
|
from kivymd.uix.behaviors import (
|
||||||
CircularRippleBehavior,
|
CircularRippleBehavior,
|
||||||
CommonElevationBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
)
|
)
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
|
@ -244,7 +194,7 @@ with open(
|
||||||
|
|
||||||
class BaseDialogPicker(
|
class BaseDialogPicker(
|
||||||
BaseDialog,
|
BaseDialog,
|
||||||
CommonElevationBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -305,11 +255,11 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
primary_color = ColorProperty(None)
|
primary_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color of toolbar in (r, g, b, a) or string format.
|
Background color of toolbar in (r, g, b, a) format.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(primary_color="brown")
|
MDDatePicker(primary_color=get_color_from_hex("#72225b"))
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-color-date.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -320,13 +270,13 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
accent_color = ColorProperty(None)
|
accent_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color of calendar/clock face in (r, g, b, a) or string format.
|
Background color of calendar/clock face in (r, g, b, a) format.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/accent-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/accent-color-date.png
|
||||||
|
@ -338,15 +288,14 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
selector_color = ColorProperty(None)
|
selector_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color of the selected day of the month or hour in (r, g, b, a)
|
Background color of the selected day of the month or hour in (r, g, b, a) format.
|
||||||
or string format.
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/selector-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/selector-color-date.png
|
||||||
|
@ -358,15 +307,15 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
text_toolbar_color = ColorProperty(None)
|
text_toolbar_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Color of labels for text on a toolbar in (r, g, b, a) or string format.
|
Color of labels for text on a toolbar in (r, g, b, a) format.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-toolbar-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-toolbar-color-date.png
|
||||||
|
@ -378,16 +327,16 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
text_color = ColorProperty(None)
|
text_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Color of text labels in calendar/clock face in (r, g, b, a) or string format.
|
Color of text labels in calendar/clock face in (r, g, b, a) format.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-color-date.png
|
||||||
|
@ -399,18 +348,17 @@ class BaseDialogPicker(
|
||||||
|
|
||||||
text_current_color = ColorProperty(None)
|
text_current_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Color of the text of the current day of the month/hour in (r, g, b, a)
|
Color of the text of the current day of the month/hour in (r, g, b, a) format.
|
||||||
or string format.
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
text_current_color="white",
|
text_current_color=get_color_from_hex("#e93f39"),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-current-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-current-color-date.png
|
||||||
|
@ -427,13 +375,13 @@ class BaseDialogPicker(
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
text_current_color="white",
|
text_current_color=get_color_from_hex("#e93f39"),
|
||||||
text_button_color="lightgrey",
|
text_button_color=(1, 1, 1, .5),
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-button-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-button-color-date.png
|
||||||
|
@ -443,124 +391,52 @@ class BaseDialogPicker(
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
input_field_background_color_normal = ColorProperty(None)
|
input_field_background_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Background color normal of input fields in (r, g, b, a) or string format.
|
Background color of input fields in (r, g, b, a) format.
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
text_current_color="white",
|
text_current_color=get_color_from_hex("#e93f39"),
|
||||||
text_button_color="lightgrey",
|
input_field_background_color=(1, 1, 1, 0.2),
|
||||||
input_field_background_color_normal="coral",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-background-color-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-background-color-date.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`input_field_background_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`input_field_background_color` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
input_field_background_color_focus = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
Background color normal of input fields in (r, g, b, a) or string format.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDDatePicker(
|
|
||||||
primary_color="brown",
|
|
||||||
accent_color="darkred",
|
|
||||||
selector_color="red",
|
|
||||||
text_toolbar_color="lightgrey",
|
|
||||||
text_color="orange",
|
|
||||||
text_current_color="white",
|
|
||||||
text_button_color="lightgrey",
|
|
||||||
input_field_background_color_normal="coral",
|
|
||||||
input_field_background_color_focus="red",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-background-color-focus-date.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`input_field_background_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_field_background_color = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
.. deprecated:: 1.1.0
|
|
||||||
Use :attr:`input_field_background_color_normal` instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_field_text_color = ColorProperty(None)
|
input_field_text_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
.. deprecated:: 1.1.0
|
Text color of input fields in (r, g, b, a) format.
|
||||||
Use :attr:`input_field_text_color_normal` instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_field_text_color_normal = ColorProperty(None)
|
Background color of input fields.
|
||||||
"""
|
|
||||||
Text color normal of input fields in (r, g, b, a) or string format.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
text_current_color="white",
|
text_current_color=get_color_from_hex("#e93f39"),
|
||||||
text_button_color="lightgrey",
|
input_field_background_color=(1, 1, 1, 0.2),
|
||||||
input_field_background_color_normal="brown",
|
input_field_text_color=(1, 1, 1, 1),
|
||||||
input_field_background_color_focus="red",
|
|
||||||
input_field_text_color_normal="white",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-text-color-normal-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-background-color-date.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`input_field_text_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`input_field_text_color` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
input_field_text_color_focus = ColorProperty(None)
|
|
||||||
"""
|
|
||||||
Text color focus of input fields in (r, g, b, a) or string format.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDDatePicker(
|
|
||||||
primary_color="brown",
|
|
||||||
accent_color="darkred",
|
|
||||||
selector_color="red",
|
|
||||||
text_toolbar_color="lightgrey",
|
|
||||||
text_color="orange",
|
|
||||||
text_current_color="white",
|
|
||||||
text_button_color="lightgrey",
|
|
||||||
input_field_background_color_normal="brown",
|
|
||||||
input_field_background_color_focus="red",
|
|
||||||
input_field_text_color_normal="white",
|
|
||||||
)
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/input-field-text-color-normal-date.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`input_field_text_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -571,18 +447,16 @@ class BaseDialogPicker(
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDDatePicker(
|
MDDatePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="darkred",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
selector_color="red",
|
selector_color=get_color_from_hex("#e93f39"),
|
||||||
text_toolbar_color="lightgrey",
|
text_toolbar_color=get_color_from_hex("#cccccc"),
|
||||||
text_color="orange",
|
text_color=("#ffffff"),
|
||||||
text_current_color="white",
|
text_current_color=get_color_from_hex("#e93f39"),
|
||||||
text_button_color="lightgrey",
|
input_field_background_color=(1, 1, 1, 0.2),
|
||||||
input_field_background_color_normal="brown",
|
input_field_text_color=(1, 1, 1, 1),
|
||||||
input_field_background_color_focus="red",
|
font_name="Weather.ttf",
|
||||||
input_field_text_color_normal="white",
|
|
||||||
input_field_text_color_focus="lightgrey",
|
|
||||||
font_name="nasalization.ttf",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-name-date.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-name-date.png
|
||||||
|
@ -597,20 +471,6 @@ class BaseDialogPicker(
|
||||||
self.register_event_type("on_save")
|
self.register_event_type("on_save")
|
||||||
self.register_event_type("on_cancel")
|
self.register_event_type("on_cancel")
|
||||||
|
|
||||||
def on_input_field_background_color(
|
|
||||||
self, instance, value: str | list | tuple
|
|
||||||
) -> None:
|
|
||||||
"""For supported of current API."""
|
|
||||||
|
|
||||||
self.input_field_background_color_normal = value
|
|
||||||
|
|
||||||
def on_input_field_text_color(
|
|
||||||
self, instance, value: str | list | tuple
|
|
||||||
) -> None:
|
|
||||||
"""For supported of current API."""
|
|
||||||
|
|
||||||
self.input_field_text_color_normal = value
|
|
||||||
|
|
||||||
def on_save(self, *args) -> None:
|
def on_save(self, *args) -> None:
|
||||||
"""Events called when the "OK" dialog box button is clicked."""
|
"""Events called when the "OK" dialog box button is clicked."""
|
||||||
|
|
||||||
|
@ -746,13 +606,6 @@ class DatePickerDaySelectableItem(
|
||||||
|
|
||||||
self.owner.set_selected_widget(self)
|
self.owner.set_selected_widget(self)
|
||||||
|
|
||||||
def on_touch_down(self, touch):
|
|
||||||
# If year_layout is active don't dispatch on_touch_down events,
|
|
||||||
# so date items don't consume touch.
|
|
||||||
if not self.owner.ids._year_layout.disabled:
|
|
||||||
return
|
|
||||||
super().on_touch_down(touch)
|
|
||||||
|
|
||||||
|
|
||||||
class DatePickerYearSelectableItem(RecycleDataViewBehavior, MDLabel):
|
class DatePickerYearSelectableItem(RecycleDataViewBehavior, MDLabel):
|
||||||
"""Implements an item for a pick list of the year."""
|
"""Implements an item for a pick list of the year."""
|
||||||
|
@ -808,7 +661,7 @@ class DatePickerYearSelectableItem(RecycleDataViewBehavior, MDLabel):
|
||||||
class MDDatePicker(BaseDialogPicker):
|
class MDDatePicker(BaseDialogPicker):
|
||||||
text_weekday_color = ColorProperty(None)
|
text_weekday_color = ColorProperty(None)
|
||||||
"""
|
"""
|
||||||
Text color of weekday names in (r, g, b, a) or string format.
|
Text color of weekday names in (r, g, b, a) format.
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-date-picker-text-weekday-color.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-date-picker-text-weekday-color.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -1347,39 +1200,19 @@ class MDDatePicker(BaseDialogPicker):
|
||||||
"""Creates and returns a text field object used to enter dates."""
|
"""Creates and returns a text field object used to enter dates."""
|
||||||
|
|
||||||
if issubclass(self.input_field_cls, MDTextField):
|
if issubclass(self.input_field_cls, MDTextField):
|
||||||
text_color_focus = (
|
|
||||||
self.input_field_text_color_focus
|
|
||||||
if self.input_field_text_color_focus
|
|
||||||
else self.theme_cls.primary_color
|
|
||||||
)
|
|
||||||
text_color_normal = (
|
|
||||||
self.input_field_text_color_normal
|
|
||||||
if self.input_field_text_color_normal
|
|
||||||
else self.theme_cls.disabled_hint_text_color
|
|
||||||
)
|
|
||||||
fill_color_focus = (
|
|
||||||
self.input_field_background_color_focus
|
|
||||||
if self.input_field_background_color_focus
|
|
||||||
else self.theme_cls.bg_dark
|
|
||||||
)
|
|
||||||
fill_color_normal = (
|
|
||||||
self.input_field_background_color_normal
|
|
||||||
if self.input_field_background_color_normal
|
|
||||||
else self.theme_cls.bg_darkest
|
|
||||||
)
|
|
||||||
|
|
||||||
field = self.input_field_cls(
|
field = self.input_field_cls(
|
||||||
owner=self,
|
owner=self,
|
||||||
helper_text=self.helper_text,
|
helper_text=self.helper_text,
|
||||||
fill_color_normal=fill_color_normal,
|
line_color_normal=self.theme_cls.divider_color,
|
||||||
fill_color_focus=fill_color_focus,
|
|
||||||
hint_text_color_normal=text_color_normal,
|
|
||||||
hint_text_color_focus=text_color_focus,
|
|
||||||
text_color_normal=text_color_normal,
|
|
||||||
text_color_focus=text_color_focus,
|
|
||||||
line_color_focus=text_color_focus,
|
|
||||||
line_color_normal=text_color_normal,
|
|
||||||
)
|
)
|
||||||
|
field.color_mode = "custom"
|
||||||
|
field.line_color_focus = (
|
||||||
|
self.theme_cls.primary_color
|
||||||
|
if not self.input_field_text_color
|
||||||
|
else self.input_field_text_color
|
||||||
|
)
|
||||||
|
field.current_hint_text_color = field.line_color_focus
|
||||||
|
field._current_hint_text_color = field.line_color_focus
|
||||||
return field
|
return field
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
|
|
@ -16,73 +16,35 @@ Components/TimePicker
|
||||||
|
|
||||||
.. rubric:: Usage
|
.. rubric:: Usage
|
||||||
|
|
||||||
.. tabs::
|
.. code-block::
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
from kivymd.uix.pickers import MDTimePicker
|
||||||
|
|
||||||
from kivy.lang import Builder
|
KV = '''
|
||||||
|
MDFloatLayout:
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
MDRaisedButton:
|
||||||
from kivymd.uix.pickers import MDTimePicker
|
text: "Open time picker"
|
||||||
|
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||||
KV = '''
|
on_release: app.show_time_picker()
|
||||||
MDFloatLayout:
|
'''
|
||||||
|
|
||||||
MDRaisedButton:
|
|
||||||
text: "Open time picker"
|
|
||||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
|
||||||
on_release: app.show_time_picker()
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
class Test(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(KV)
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
def show_time_picker(self):
|
def show_time_picker(self):
|
||||||
'''Open time picker dialog.'''
|
'''Open time picker dialog.'''
|
||||||
|
|
||||||
time_dialog = MDTimePicker()
|
time_dialog = MDTimePicker()
|
||||||
time_dialog.open()
|
time_dialog.open()
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
Test().run()
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.button import MDRaisedButton
|
|
||||||
from kivymd.uix.pickers import MDTimePicker
|
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return (
|
|
||||||
MDScreen(
|
|
||||||
MDRaisedButton(
|
|
||||||
text="Open time picker",
|
|
||||||
pos_hint={'center_x': .5, 'center_y': .5},
|
|
||||||
on_release=self.show_time_picker,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def show_time_picker(self, *args):
|
|
||||||
'''Open time picker dialog.'''
|
|
||||||
|
|
||||||
MDTimePicker().open()
|
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/MDTimePicker.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/MDTimePicker.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -129,14 +91,14 @@ Use the :attr:`~MDTimePicker.set_time` method of the
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
MDTimePicker(
|
time_dialog = MDTimePicker(
|
||||||
primary_color="brown",
|
primary_color=get_color_from_hex("#72225b"),
|
||||||
accent_color="red",
|
accent_color=get_color_from_hex("#5d1a4a"),
|
||||||
text_button_color="white",
|
text_button_color=(1, 1, 1, 1),
|
||||||
).open()
|
)
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/time-picker-customization.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/time-picker-customization.png
|
||||||
:align: center
|
:align: center
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ("MDTimePicker",)
|
__all__ = ("MDTimePicker",)
|
||||||
|
@ -232,8 +194,8 @@ class TimeInputTextField(MDTextField):
|
||||||
hour_regx = "^[0-9]$|^0[1-9]$|^1[0-2]$"
|
hour_regx = "^[0-9]$|^0[1-9]$|^1[0-2]$"
|
||||||
minute_regx = "^[0-9]$|^0[0-9]$|^[1-5][0-9]$"
|
minute_regx = "^[0-9]$|^0[0-9]$|^[1-5][0-9]$"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
Clock.schedule_once(self.set_text)
|
Clock.schedule_once(self.set_text)
|
||||||
self.register_event_type("on_select")
|
self.register_event_type("on_select")
|
||||||
self.bind(text_color_focus=self.setter("hint_text_color_normal"))
|
self.bind(text_color_focus=self.setter("hint_text_color_normal"))
|
||||||
|
@ -255,20 +217,17 @@ class TimeInputTextField(MDTextField):
|
||||||
to somehow make them aligned.
|
to somehow make them aligned.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def set_text(*args):
|
if not self.text:
|
||||||
if not self.text:
|
self.text = " "
|
||||||
self.text = " "
|
|
||||||
|
|
||||||
self._refresh_text(self.text)
|
self._refresh_text(self.text)
|
||||||
max_size = max(self._lines_rects, key=lambda r: r.size[0]).size
|
max_size = max(self._lines_rects, key=lambda r: r.size[0]).size
|
||||||
dx = (self.width - max_size[0]) / 2.0
|
dx = (self.width - max_size[0]) / 2.0
|
||||||
dy = (self.height - max_size[1]) / 2.0
|
dy = (self.height - max_size[1]) / 2.0
|
||||||
self.padding = [dx, dy, dx, dy]
|
self.padding = [dx, dy, dx, dy]
|
||||||
|
|
||||||
if len(self.text) > 1:
|
if len(self.text) > 1:
|
||||||
self.text = self.text.replace(" ", "")
|
self.text = self.text.replace(" ", "")
|
||||||
|
|
||||||
Clock.schedule_once(set_text)
|
|
||||||
|
|
||||||
def on_focus(self, *args) -> None:
|
def on_focus(self, *args) -> None:
|
||||||
super().on_focus(*args)
|
super().on_focus(*args)
|
||||||
|
|
|
@ -36,7 +36,7 @@ Example
|
||||||
title: app.title
|
title: app.title
|
||||||
md_bg_color: app.theme_cls.primary_color
|
md_bg_color: app.theme_cls.primary_color
|
||||||
background_palette: 'Primary'
|
background_palette: 'Primary'
|
||||||
elevation: 4
|
elevation: 10
|
||||||
left_action_items: [['menu', lambda x: x]]
|
left_action_items: [['menu', lambda x: x]]
|
||||||
|
|
||||||
MDScrollViewRefreshLayout:
|
MDScrollViewRefreshLayout:
|
||||||
|
|
|
@ -29,7 +29,7 @@ MDScreen
|
||||||
md_bg_color: app.theme_cls.primary_color
|
md_bg_color: app.theme_cls.primary_color
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from kivy.properties import ListProperty, ObjectProperty
|
from kivy.properties import ObjectProperty
|
||||||
from kivy.uix.screenmanager import Screen
|
from kivy.uix.screenmanager import Screen
|
||||||
|
|
||||||
from kivymd.uix import MDAdaptiveWidget
|
from kivymd.uix import MDAdaptiveWidget
|
||||||
|
@ -44,34 +44,20 @@ class MDScreen(DeclarativeBehavior, Screen, MDAdaptiveWidget):
|
||||||
see in the :class:`~kivy.uix.screenmanager.Screen` class documentation.
|
see in the :class:`~kivy.uix.screenmanager.Screen` class documentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hero_to = ObjectProperty(deprecated=True)
|
hero_to = ObjectProperty()
|
||||||
"""
|
"""
|
||||||
Must be a :class:`~kivymd.uix.hero.MDHeroTo` class.
|
Must be a :class:`~kivymd.uix.hero.MDHeroTo` class.
|
||||||
|
|
||||||
See the documentation of the
|
See the documentation of the
|
||||||
`MDHeroTo <https://kivymd.readthedocs.io/en/latest/components/hero/>`_
|
`MDHeroTo <https://kivymd.readthedocs.io/en/latest/components/hero/>`_
|
||||||
widget for more detailed information.
|
widget for more detailed information.
|
||||||
|
|
||||||
.. deprecated:: 1.0.0
|
.. versionchanged:: 1.0.0
|
||||||
Use attr:`heroes_to` attribute instead.
|
|
||||||
|
|
||||||
:attr:`hero_to` is an :class:`~kivy.properties.ObjectProperty`
|
:attr:`hero_to` is an :class:`~kivy.properties.ObjectProperty`
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
heroes_to = ListProperty()
|
def on_hero_to(self, screen, widget) -> None:
|
||||||
"""
|
|
||||||
Must be a list of :class:`~kivymd.uix.hero.MDHeroTo` class.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
|
||||||
|
|
||||||
:attr:`heroes_to` is an :class:`~kivy.properties.LiatProperty`
|
|
||||||
and defaults to `[]`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def on_hero_to(self, screen, widget: MDHeroTo) -> None:
|
|
||||||
"""Called when the value of the :attr:`hero_to` attribute changes."""
|
|
||||||
|
|
||||||
if not isinstance(widget, MDHeroTo) or not issubclass(
|
if not isinstance(widget, MDHeroTo) or not issubclass(
|
||||||
widget.__class__, MDHeroTo
|
widget.__class__, MDHeroTo
|
||||||
):
|
):
|
||||||
|
@ -79,4 +65,3 @@ class MDScreen(DeclarativeBehavior, Screen, MDAdaptiveWidget):
|
||||||
f"The `{widget}` widget must be an `kivymd.uix.hero.MDHeroTo` "
|
f"The `{widget}` widget must be an `kivymd.uix.hero.MDHeroTo` "
|
||||||
f"class or inherited from this class"
|
f"class or inherited from this class"
|
||||||
)
|
)
|
||||||
self.heroes_to = [widget]
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ If you want to use Hero animations you need to use
|
||||||
:class:`~kivy.uix.screenmanager.ScreenManager` class.
|
:class:`~kivy.uix.screenmanager.ScreenManager` class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from kivy import Logger
|
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.properties import ListProperty, StringProperty
|
from kivy.properties import ListProperty, StringProperty
|
||||||
from kivy.uix.screenmanager import ScreenManager
|
from kivy.uix.screenmanager import ScreenManager
|
||||||
|
@ -22,22 +21,17 @@ from kivymd.uix.hero import MDHeroFrom
|
||||||
class MDScreenManager(DeclarativeBehavior, ScreenManager):
|
class MDScreenManager(DeclarativeBehavior, ScreenManager):
|
||||||
"""
|
"""
|
||||||
Screen manager. This is the main class that will control your
|
Screen manager. This is the main class that will control your
|
||||||
:class:`~kivymd.uix.screen.MDScreen` stack and memory.
|
:class:`~kivymd.uix.screen.MDScreen` stack and memory. For more
|
||||||
|
|
||||||
For more
|
|
||||||
information, see in the :class:`~kivy.uix.screenmanager.ScreenManager`
|
information, see in the :class:`~kivy.uix.screenmanager.ScreenManager`
|
||||||
class documentation.
|
class documentation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
current_hero = StringProperty(None, deprecated=True)
|
current_hero = StringProperty(None)
|
||||||
"""
|
"""
|
||||||
The name of the current tag for the :class:`~kivymd.uix.hero.MDHeroFrom`
|
The name of the current tag for the :class:`~kivymd.uix.hero.MDHeroFrom`
|
||||||
and :class:`~kivymd.uix.hero.MDHeroTo` objects that will be animated when
|
and :class:`~kivymd.uix.hero.MDHeroTo` objects that will be animated when
|
||||||
animating the transition between screens.
|
animating the transition between screens.
|
||||||
|
|
||||||
.. deprecated:: 1.1.0
|
|
||||||
Use :attr:`current_heroes` attribute instead.
|
|
||||||
|
|
||||||
See the `Hero <https://kivymd.readthedocs.io/en/latest/components/hero/>`_
|
See the `Hero <https://kivymd.readthedocs.io/en/latest/components/hero/>`_
|
||||||
module documentation for more information about creating and using Hero
|
module documentation for more information about creating and using Hero
|
||||||
animations.
|
animations.
|
||||||
|
@ -46,17 +40,6 @@ class MDScreenManager(DeclarativeBehavior, ScreenManager):
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
current_heroes = ListProperty()
|
|
||||||
"""
|
|
||||||
A list of names (tags) of heroes that need to be animated when moving
|
|
||||||
to the next screen.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
:attr:`current_heroes` is an :class:`~kivy.properties.ListProperty`
|
|
||||||
and defaults to `[]`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Collection of `MDHeroFrom` objects on all screens of the current
|
# Collection of `MDHeroFrom` objects on all screens of the current
|
||||||
# screen manager.
|
# screen manager.
|
||||||
_heroes_data = ListProperty()
|
_heroes_data = ListProperty()
|
||||||
|
@ -75,48 +58,28 @@ class MDScreenManager(DeclarativeBehavior, ScreenManager):
|
||||||
|
|
||||||
self.transition = MDSlideTransition()
|
self.transition = MDSlideTransition()
|
||||||
|
|
||||||
def get_hero_from_widget(self) -> list:
|
def get_hero_from_widget(self) -> None:
|
||||||
"""
|
"""
|
||||||
Get a list of :class:`~kivymd.uix.hero.MDHeroFrom` objects according
|
Get an :class:`~kivymd.uix.hero.MDHeroTo` object with the
|
||||||
to the tag names specified in the :attr:`~current_heroes` list.
|
:attr:`~current_hero` tag.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hero_from_widget = []
|
hero_from_widget = None
|
||||||
|
|
||||||
for name_hero in self.current_heroes:
|
for hero_widget in self._heroes_data:
|
||||||
for hero_widget in self._heroes_data:
|
if isinstance(hero_widget, MDHeroFrom) or issubclass(
|
||||||
if isinstance(hero_widget, MDHeroFrom) or issubclass(
|
hero_widget.__class__, MDHeroFrom
|
||||||
hero_widget.__class__, MDHeroFrom
|
):
|
||||||
):
|
if hero_widget.tag == self.current_hero:
|
||||||
if hero_widget.tag == name_hero:
|
hero_from_widget = hero_widget
|
||||||
hero_from_widget.append(hero_widget)
|
break
|
||||||
|
|
||||||
return hero_from_widget
|
return hero_from_widget
|
||||||
|
|
||||||
def on_current_hero(self, instance, value: str) -> None:
|
|
||||||
"""
|
|
||||||
Called when the value of the :attr:`current_hero` attribute changes.
|
|
||||||
"""
|
|
||||||
|
|
||||||
Logger.warning(
|
|
||||||
"KivyMD: "
|
|
||||||
"`kivymd/uix/screenmanager.MDScreenManager.current_hero` "
|
|
||||||
"attribute is deprecated. "
|
|
||||||
"Use `kivymd/uix/screenmanager.MDScreenManager.current_heroes` "
|
|
||||||
"attribute instead."
|
|
||||||
)
|
|
||||||
if value:
|
|
||||||
self.current_heroes = [value]
|
|
||||||
else:
|
|
||||||
self.current_heroes = []
|
|
||||||
|
|
||||||
def add_widget(self, widget, *args, **kwargs):
|
def add_widget(self, widget, *args, **kwargs):
|
||||||
super().add_widget(widget, *args, **kwargs)
|
super().add_widget(widget, *args, **kwargs)
|
||||||
Clock.schedule_once(lambda x: self._create_heroes_data(widget))
|
Clock.schedule_once(lambda x: self._create_heroes_data(widget))
|
||||||
|
|
||||||
# TODO: Add a method to delete an object from the arrt:`_heroes_data`
|
|
||||||
# collection when deleting an object using the `remove_widget` method.
|
|
||||||
|
|
||||||
def _create_heroes_data(self, widget):
|
def _create_heroes_data(self, widget):
|
||||||
def find_hero_widget(child_widget):
|
def find_hero_widget(child_widget):
|
||||||
widget_hero = None
|
widget_hero = None
|
||||||
|
|
|
@ -15,11 +15,8 @@
|
||||||
pos_hint: {"center_y": .5}
|
pos_hint: {"center_y": .5}
|
||||||
x: root._segment_switch_x
|
x: root._segment_switch_x
|
||||||
md_bg_color: root.segment_color
|
md_bg_color: root.segment_color
|
||||||
elevation: 2
|
elevation: 6
|
||||||
_radius: root.radius[0] - 4
|
_radius: root.radius[0] - 4
|
||||||
width:
|
|
||||||
segment_panel.width / segment_panel.children_number \
|
|
||||||
- segment_panel.spacing
|
|
||||||
|
|
||||||
SegmentPanel:
|
SegmentPanel:
|
||||||
id: segment_panel
|
id: segment_panel
|
||||||
|
|
|
@ -10,77 +10,58 @@ Components/SegmentedControl
|
||||||
Usage
|
Usage
|
||||||
=====
|
=====
|
||||||
|
|
||||||
.. tabs::
|
.. code-block:: python
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
from kivy.lang import Builder
|
||||||
|
|
||||||
.. code-block:: python
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
from kivy.lang import Builder
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
MDScreen:
|
MDScreen:
|
||||||
|
|
||||||
MDSegmentedControl:
|
MDSegmentedControl:
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
|
||||||
MDSegmentedControlItem:
|
MDSegmentedControlItem:
|
||||||
text: "Male"
|
text: "Male"
|
||||||
|
|
||||||
MDSegmentedControlItem:
|
MDSegmentedControlItem:
|
||||||
text: "Female"
|
text: "Female"
|
||||||
|
|
||||||
MDSegmentedControlItem:
|
MDSegmentedControlItem:
|
||||||
text: "All"
|
text: "All"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Test(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
return Builder.load_string(KV)
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
Test().run()
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
Or only in python code:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
from kivymd.uix.screen import MDScreen
|
from kivymd.uix.screen import MDScreen
|
||||||
from kivymd.uix.segmentedcontrol import (
|
from kivymd.uix.segmentedcontrol import MDSegmentedControl, MDSegmentedControlItem
|
||||||
MDSegmentedControl, MDSegmentedControlItem
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Test(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
screen = MDScreen()
|
||||||
self.theme_cls.primary_palette = "Orange"
|
segment_control = MDSegmentedControl(pos_hint={"center_x": .5, "center_y": .5})
|
||||||
return (
|
segment_control.add_widget(MDSegmentedControlItem(text="Male"))
|
||||||
MDScreen(
|
segment_control.add_widget(MDSegmentedControlItem(text="Female"))
|
||||||
MDSegmentedControl(
|
segment_control.add_widget(MDSegmentedControlItem(text="All"))
|
||||||
MDSegmentedControlItem(
|
screen.add_widget(segment_control)
|
||||||
text="Male"
|
return screen
|
||||||
),
|
|
||||||
MDSegmentedControlItem(
|
|
||||||
text="Female"
|
|
||||||
),
|
|
||||||
MDSegmentedControlItem(
|
|
||||||
text="All"
|
|
||||||
),
|
|
||||||
pos_hint={"center_x": 0.5, "center_y": 0.5}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Example().run()
|
Test().run()
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-usage.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-usage.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -136,22 +117,12 @@ with open(
|
||||||
|
|
||||||
|
|
||||||
class MDSegmentedControlItem(MDLabel):
|
class MDSegmentedControlItem(MDLabel):
|
||||||
"""
|
"""Implements a label to place on the :class:`~SegmentPanel` panel."""
|
||||||
Implements a label to place on the :class:`~SegmentPanel` panel.
|
|
||||||
|
|
||||||
See :class:`~kivymd.uix.label.MDLabel` class documentation for more
|
|
||||||
information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add an attribute for the color of the active segment label.
|
# TODO: Add an attribute for the color of the active segment label.
|
||||||
class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
"""
|
"""
|
||||||
Implements a segmented control panel.
|
|
||||||
|
|
||||||
Relative layout class. For more information, see in the
|
|
||||||
:class:`~kivy.uix.relativelayout.RelativeLayout` class documentation.
|
|
||||||
|
|
||||||
:Events:
|
:Events:
|
||||||
`on_active`
|
`on_active`
|
||||||
Called when the segment is activated.
|
Called when the segment is activated.
|
||||||
|
@ -164,7 +135,7 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDSegmentedControl:
|
MDSegmentedControl:
|
||||||
md_bg_color: "brown"
|
md_bg_color: "#451938"
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-md-bg-color.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-md-bg-color.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -180,8 +151,8 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDSegmentedControl:
|
MDSegmentedControl:
|
||||||
md_bg_color: "brown"
|
md_bg_color: "#451938"
|
||||||
segment_color: "red"
|
segment_color: "#e4514f"
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-segment-color.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-segment-color.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -189,8 +160,8 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDSegmentedControl:
|
MDSegmentedControl:
|
||||||
md_bg_color: "brown"
|
md_bg_color: "#451938"
|
||||||
segment_color: "red"
|
segment_color: "#e4514f"
|
||||||
|
|
||||||
MDSegmentedControlItem:
|
MDSegmentedControlItem:
|
||||||
text: "[color=fff]Male[/color]"
|
text: "[color=fff]Male[/color]"
|
||||||
|
@ -225,9 +196,9 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDSegmentedControl:
|
MDSegmentedControl:
|
||||||
md_bg_color: "brown"
|
md_bg_color: "#451938"
|
||||||
segment_color: "red"
|
segment_color: "#e4514f"
|
||||||
separator_color: "white"
|
separator_color: 1, 1, 1, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-separator-color.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-segmented-control-separator-color.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -284,6 +255,9 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
|
|
||||||
Clock.schedule_once(self.set_default_colors)
|
Clock.schedule_once(self.set_default_colors)
|
||||||
Clock.schedule_once(self._remove_last_separator)
|
Clock.schedule_once(self._remove_last_separator)
|
||||||
|
# FIXME: Sometimes this interval is not enough to get the width
|
||||||
|
# of the segment label textures.
|
||||||
|
Clock.schedule_once(self._set_width_segment_switch, 2.2)
|
||||||
|
|
||||||
def set_default_colors(self, *args) -> None:
|
def set_default_colors(self, *args) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -339,10 +313,6 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
self.ids.segment_panel.add_widget(widget)
|
self.ids.segment_panel.add_widget(widget)
|
||||||
separator = MDSeparator(orientation="vertical")
|
separator = MDSeparator(orientation="vertical")
|
||||||
self.ids.segment_panel.add_widget(separator)
|
self.ids.segment_panel.add_widget(separator)
|
||||||
if not self.ids.segment_panel._started:
|
|
||||||
self.ids.segment_panel._started = True
|
|
||||||
else:
|
|
||||||
self.ids.segment_panel.children_number += 1
|
|
||||||
Clock.schedule_once(
|
Clock.schedule_once(
|
||||||
lambda x: self.update_separator_color(separator)
|
lambda x: self.update_separator_color(separator)
|
||||||
)
|
)
|
||||||
|
@ -356,6 +326,15 @@ class MDSegmentedControl(MDRelativeLayout, ThemableBehavior):
|
||||||
self.current_active_segment = widget
|
self.current_active_segment = widget
|
||||||
self.dispatch("on_active", widget)
|
self.dispatch("on_active", widget)
|
||||||
|
|
||||||
|
def _set_width_segment_switch(self, *args):
|
||||||
|
"""
|
||||||
|
Sets the width of the switch. I think this is not done quite correctly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.ids.segment_switch.width = self.ids.segment_panel.children[
|
||||||
|
0
|
||||||
|
].width + dp(12)
|
||||||
|
|
||||||
def _remove_last_separator(self, *args):
|
def _remove_last_separator(self, *args):
|
||||||
self.ids.segment_panel.remove_widget(self.ids.segment_panel.children[0])
|
self.ids.segment_panel.remove_widget(self.ids.segment_panel.children[0])
|
||||||
|
|
||||||
|
@ -371,7 +350,3 @@ class SegmentPanel(MDBoxLayout):
|
||||||
Implements a panel for placing items - :class:`~MDSegmentedControlItem`
|
Implements a panel for placing items - :class:`~MDSegmentedControlItem`
|
||||||
for the :class:`~MDSegmentedControl` class.
|
for the :class:`~MDSegmentedControl` class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
children_number = NumericProperty(1)
|
|
||||||
|
|
||||||
_started = BooleanProperty(defaultvalue=False)
|
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
size: dp(24), dp(24)
|
size: dp(24), dp(24)
|
||||||
elevation:
|
elevation:
|
||||||
(2.5 if root.active else 1) \
|
(8 if root.active else 5) \
|
||||||
if app.theme_cls.material_style != "M3" else \
|
if app.theme_cls.material_style != "M3" else \
|
||||||
0
|
0
|
||||||
pos:
|
pos:
|
||||||
|
|
|
@ -192,10 +192,15 @@ from kivy.properties import (
|
||||||
)
|
)
|
||||||
from kivy.uix.behaviors import ToggleButtonBehavior
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
from kivy.uix.floatlayout import FloatLayout
|
from kivy.uix.floatlayout import FloatLayout
|
||||||
|
from kivy.utils import get_color_from_hex
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
from kivymd.color_definitions import colors
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import CircularRippleBehavior, CommonElevationBehavior
|
from kivymd.uix.behaviors import (
|
||||||
|
CircularRippleBehavior,
|
||||||
|
FakeCircularElevationBehavior,
|
||||||
|
)
|
||||||
from kivymd.uix.floatlayout import MDFloatLayout
|
from kivymd.uix.floatlayout import MDFloatLayout
|
||||||
from kivymd.uix.label import MDIcon
|
from kivymd.uix.label import MDIcon
|
||||||
|
|
||||||
|
@ -356,10 +361,8 @@ class MDCheckbox(CircularRippleBehavior, ToggleButtonBehavior, MDIcon):
|
||||||
disabled=self.update_color,
|
disabled=self.update_color,
|
||||||
state=self.update_color,
|
state=self.update_color,
|
||||||
)
|
)
|
||||||
self.theme_cls.bind(
|
self.theme_cls.bind(primary_color=self.update_primary_color)
|
||||||
theme_style=self.update_primary_color,
|
self.theme_cls.bind(theme_style=self.update_primary_color)
|
||||||
primary_color=self.update_primary_color,
|
|
||||||
)
|
|
||||||
self.update_icon()
|
self.update_icon()
|
||||||
self.update_color()
|
self.update_color()
|
||||||
|
|
||||||
|
@ -420,7 +423,7 @@ class ThumbIcon(MDIcon):
|
||||||
|
|
||||||
|
|
||||||
class Thumb(
|
class Thumb(
|
||||||
CommonElevationBehavior,
|
FakeCircularElevationBehavior,
|
||||||
CircularRippleBehavior,
|
CircularRippleBehavior,
|
||||||
MDFloatLayout,
|
MDFloatLayout,
|
||||||
):
|
):
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#:import colors kivymd.color_definitions.colors
|
#:import colors kivymd.color_definitions.colors
|
||||||
|
|
||||||
|
|
||||||
<HintBoxContainer@MDCard>
|
<HintBoxContainer@MDCard+FakeRectangularElevationBehavior>
|
||||||
|
|
||||||
|
|
||||||
<MDSlider>
|
<MDSlider>
|
||||||
|
@ -131,20 +131,16 @@
|
||||||
) \
|
) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
elevation: 0 if root._is_off else (3 if root.active else 1)
|
elevation: 0 if root._is_off else (4 if root.active else 2)
|
||||||
|
|
||||||
HintBoxContainer:
|
HintBoxContainer:
|
||||||
id: hint_box
|
id: hint_box
|
||||||
size_hint: None, None
|
size_hint: None, None
|
||||||
md_bg_color: root.hint_bg_color if root.hint_bg_color else [0, 0, 0, 0]
|
md_bg_color: root.hint_bg_color
|
||||||
elevation: 1.5
|
elevation: 0
|
||||||
opacity: 1 if root.active else 0
|
opacity: 1 if root.active else 0
|
||||||
radius: root.hint_radius
|
radius: root.hint_radius
|
||||||
padding: "6dp", "6dp", "6dp", "8dp"
|
padding: "6dp", "6dp", "6dp", "8dp"
|
||||||
shadow_color:
|
|
||||||
([0, 0, 0, 0.6] if root.hint_bg_color else [0, 0, 0, 0]) \
|
|
||||||
if root.active else \
|
|
||||||
[0, 0, 0, 0]
|
|
||||||
size:
|
size:
|
||||||
lbl_value.width + self.padding[0] * 2, \
|
lbl_value.width + self.padding[0] * 2, \
|
||||||
lbl_value.height + self.padding[0]
|
lbl_value.height + self.padding[0]
|
||||||
|
|
|
@ -82,7 +82,7 @@ class MDSlider(ThemableBehavior, Slider):
|
||||||
and defaults to `True`.
|
and defaults to `True`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
hint_bg_color = ColorProperty(None)
|
hint_bg_color = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Hint rectangle color in (r.g.b.a) format.
|
Hint rectangle color in (r.g.b.a) format.
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ Example
|
||||||
|
|
||||||
from kivy.lang.builder import Builder
|
from kivy.lang.builder import Builder
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
<CardItem>
|
<CardItem>
|
||||||
|
@ -47,6 +47,7 @@ Example
|
||||||
height: "86dp"
|
height: "86dp"
|
||||||
padding: "4dp"
|
padding: "4dp"
|
||||||
radius: 12
|
radius: 12
|
||||||
|
elevation: 4
|
||||||
|
|
||||||
FitImage:
|
FitImage:
|
||||||
source: "avatar.jpg"
|
source: "avatar.jpg"
|
||||||
|
@ -94,10 +95,8 @@ Example
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class CardItem(MDCard):
|
class CardItem(MDCard, RoundedRectangularElevationBehavior):
|
||||||
def __init__(self, *args, **kwargs):
|
pass
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.elevation = 3
|
|
||||||
|
|
||||||
|
|
||||||
class Example(MDApp):
|
class Example(MDApp):
|
||||||
|
@ -193,6 +192,7 @@ class MDSliverAppbar(MDBoxLayout, ThemableBehavior):
|
||||||
|
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
from kivymd.uix.toolbar import MDTopAppBar
|
from kivymd.uix.toolbar import MDTopAppBar
|
||||||
|
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
#:import SliverToolbar __main__.SliverToolbar
|
#:import SliverToolbar __main__.SliverToolbar
|
||||||
|
@ -203,6 +203,7 @@ class MDSliverAppbar(MDBoxLayout, ThemableBehavior):
|
||||||
height: "86dp"
|
height: "86dp"
|
||||||
padding: "4dp"
|
padding: "4dp"
|
||||||
radius: 12
|
radius: 12
|
||||||
|
elevation: 4
|
||||||
|
|
||||||
FitImage:
|
FitImage:
|
||||||
source: "avatar.jpg"
|
source: "avatar.jpg"
|
||||||
|
@ -251,16 +252,13 @@ class MDSliverAppbar(MDBoxLayout, ThemableBehavior):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
class CardItem(MDCard):
|
class CardItem(MDCard, RoundedRectangularElevationBehavior):
|
||||||
def __init__(self, *args, **kwargs):
|
pass
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.elevation = 3
|
|
||||||
|
|
||||||
|
|
||||||
class SliverToolbar(MDTopAppBar):
|
class SliverToolbar(MDTopAppBar):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.shadow_color = (0, 0, 0, 0)
|
|
||||||
self.type_height = "medium"
|
self.type_height = "medium"
|
||||||
self.headline_text = "Headline medium"
|
self.headline_text = "Headline medium"
|
||||||
self.left_action_items = [["arrow-left", lambda x: x]]
|
self.left_action_items = [["arrow-left", lambda x: x]]
|
||||||
|
@ -424,7 +422,6 @@ class MDSliverAppbar(MDBoxLayout, ThemableBehavior):
|
||||||
# Adding a custom MDTopAppBar object.
|
# Adding a custom MDTopAppBar object.
|
||||||
if issubclass(instance_toolbar_cls.__class__, MDTopAppBar):
|
if issubclass(instance_toolbar_cls.__class__, MDTopAppBar):
|
||||||
instance_toolbar_cls.pos_hint = {"top": 1}
|
instance_toolbar_cls.pos_hint = {"top": 1}
|
||||||
instance_toolbar_cls.elevation = 0
|
|
||||||
self.ids.float_box.add_widget(instance_toolbar_cls)
|
self.ids.float_box.add_widget(instance_toolbar_cls)
|
||||||
else:
|
else:
|
||||||
raise MDSliverAppbarException(
|
raise MDSliverAppbarException(
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
padding: "10dp", "10dp", "10dp", "10dp"
|
padding: "10dp", "10dp", "10dp", "10dp"
|
||||||
md_bg_color: "323232" if not root.bg_color else root.bg_color
|
md_bg_color: "323232" if not root.bg_color else root.bg_color
|
||||||
radius: root.radius
|
radius: root.radius
|
||||||
elevation: 4 if root.padding else 0
|
elevation: 11 if root.padding else 0
|
||||||
|
|
||||||
canvas:
|
canvas:
|
||||||
Color:
|
Color:
|
||||||
|
|
|
@ -284,6 +284,7 @@ from kivy.properties import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
from kivymd.uix.behaviors import FakeRectangularElevationBehavior
|
||||||
from kivymd.uix.button import BaseButton
|
from kivymd.uix.button import BaseButton
|
||||||
from kivymd.uix.card import MDCard
|
from kivymd.uix.card import MDCard
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class BaseSnackbar(MDCard):
|
class BaseSnackbar(MDCard, FakeRectangularElevationBehavior):
|
||||||
"""
|
"""
|
||||||
:Events:
|
:Events:
|
||||||
:attr:`on_open`
|
:attr:`on_open`
|
||||||
|
|
|
@ -38,7 +38,7 @@ Example
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
id: toolbar
|
id: toolbar
|
||||||
title: "MDSwiper"
|
title: "MDSwiper"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
|
|
||||||
MDSwiper:
|
MDSwiper:
|
||||||
|
@ -142,7 +142,7 @@ Example
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
id: toolbar
|
id: toolbar
|
||||||
title: "MDSwiper"
|
title: "MDSwiper"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
pos_hint: {"top": 1}
|
pos_hint: {"top": 1}
|
||||||
|
|
||||||
MDSwiper:
|
MDSwiper:
|
||||||
|
@ -203,6 +203,7 @@ from kivy.animation import Animation
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.effects.dampedscroll import DampedScrollEffect
|
from kivy.effects.dampedscroll import DampedScrollEffect
|
||||||
|
from kivy.event import EventDispatcher
|
||||||
from kivy.lang.builder import Builder
|
from kivy.lang.builder import Builder
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
|
@ -211,6 +212,7 @@ from kivy.properties import (
|
||||||
StringProperty,
|
StringProperty,
|
||||||
)
|
)
|
||||||
from kivy.uix.anchorlayout import AnchorLayout
|
from kivy.uix.anchorlayout import AnchorLayout
|
||||||
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.utils import platform
|
from kivy.utils import platform
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
@ -292,7 +294,7 @@ class MDSwiperItem(MDBoxLayout):
|
||||||
anim.start(self)
|
anim.start(self)
|
||||||
|
|
||||||
|
|
||||||
class MDSwiper(MDScrollView):
|
class MDSwiper(MDScrollView, EventDispatcher):
|
||||||
items_spacing = NumericProperty("20dp")
|
items_spacing = NumericProperty("20dp")
|
||||||
"""
|
"""
|
||||||
The space between each :class:`MDSwiperItem`.
|
The space between each :class:`MDSwiperItem`.
|
||||||
|
|
|
@ -79,10 +79,6 @@
|
||||||
layout: layout
|
layout: layout
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
elevation: root.elevation
|
elevation: root.elevation
|
||||||
radius: root.radius
|
|
||||||
shadow_offset: root.shadow_offset
|
|
||||||
shadow_color: root.shadow_color
|
|
||||||
shadow_softness: root.shadow_softness
|
|
||||||
height: root.tab_bar_height
|
height: root.tab_bar_height
|
||||||
md_bg_color:
|
md_bg_color:
|
||||||
self.theme_cls.primary_color \
|
self.theme_cls.primary_color \
|
||||||
|
|
|
@ -944,6 +944,7 @@ from kivy.properties import (
|
||||||
from kivy.uix.anchorlayout import AnchorLayout
|
from kivy.uix.anchorlayout import AnchorLayout
|
||||||
from kivy.uix.behaviors import ToggleButtonBehavior
|
from kivy.uix.behaviors import ToggleButtonBehavior
|
||||||
from kivy.uix.scrollview import ScrollView
|
from kivy.uix.scrollview import ScrollView
|
||||||
|
from kivy.uix.widget import Widget
|
||||||
from kivy.utils import boundary
|
from kivy.utils import boundary
|
||||||
|
|
||||||
from kivymd import uix_path
|
from kivymd import uix_path
|
||||||
|
@ -952,11 +953,11 @@ from kivymd.icon_definitions import md_icons
|
||||||
from kivymd.theming import ThemableBehavior, ThemeManager
|
from kivymd.theming import ThemableBehavior, ThemeManager
|
||||||
from kivymd.uix.behaviors import (
|
from kivymd.uix.behaviors import (
|
||||||
DeclarativeBehavior,
|
DeclarativeBehavior,
|
||||||
|
FakeRectangularElevationBehavior,
|
||||||
RectangularRippleBehavior,
|
RectangularRippleBehavior,
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
)
|
)
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
from kivymd.uix.boxlayout import MDBoxLayout
|
||||||
from kivymd.uix.card import MDCard
|
|
||||||
from kivymd.uix.carousel import MDCarousel
|
from kivymd.uix.carousel import MDCarousel
|
||||||
from kivymd.uix.label import MDLabel
|
from kivymd.uix.label import MDLabel
|
||||||
|
|
||||||
|
@ -1023,7 +1024,7 @@ class MDTabsLabel(ToggleButtonBehavior, RectangularRippleBehavior, MDLabel):
|
||||||
Clock.schedule_once(self.tab_bar._label_request_indicator_update, 0)
|
Clock.schedule_once(self.tab_bar._label_request_indicator_update, 0)
|
||||||
|
|
||||||
|
|
||||||
class MDTabsBase:
|
class MDTabsBase(Widget):
|
||||||
"""
|
"""
|
||||||
This class allow you to create a tab.
|
This class allow you to create a tab.
|
||||||
You must create a new class that inherits from MDTabsBase.
|
You must create a new class that inherits from MDTabsBase.
|
||||||
|
@ -1129,9 +1130,9 @@ class MDTabsBase:
|
||||||
This property will affect the Tab's Title Label widget.
|
This property will affect the Tab's Title Label widget.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.tab_label = MDTabsLabel(tab=self)
|
self.tab_label = MDTabsLabel(tab=self)
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
self.bind(
|
self.bind(
|
||||||
icon=self._update_text,
|
icon=self._update_text,
|
||||||
title=self._update_text,
|
title=self._update_text,
|
||||||
|
@ -1272,7 +1273,9 @@ class MDTabsScrollView(ScrollView):
|
||||||
_update(self.effect_y, scroll_y)
|
_update(self.effect_y, scroll_y)
|
||||||
|
|
||||||
|
|
||||||
class MDTabsBar(MDCard):
|
class MDTabsBar(
|
||||||
|
ThemableBehavior, FakeRectangularElevationBehavior, MDBoxLayout
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
This class is just a boxlayout that contains the scroll view for tabs.
|
This class is just a boxlayout that contains the scroll view for tabs.
|
||||||
It is also responsible for resizing the tab shortcut when necessary.
|
It is also responsible for resizing the tab shortcut when necessary.
|
||||||
|
@ -1548,43 +1551,13 @@ class MDTabs(
|
||||||
and defaults to `None`.
|
and defaults to `None`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
shadow_softness = NumericProperty(12)
|
|
||||||
"""
|
|
||||||
See :attr:`kivymd.uix.behaviors.CommonElevationBehavior.shadow_softness`
|
|
||||||
attribute.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
:attr:`shadow_softness` is an :class:`~kivy.properties.NumericProperty`
|
|
||||||
and defaults to `12`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
shadow_color = ColorProperty([0, 0, 0, 0.6])
|
|
||||||
"""
|
|
||||||
See :attr:`kivymd.uix.behaviors.CommonElevationBehavior.shadow_color`
|
|
||||||
attribute.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
:attr:`shadow_color` is an :class:`~kivy.properties.ColorProperty`
|
|
||||||
and defaults to `[0, 0, 0, 0.6]`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
shadow_offset = ListProperty((0, 0))
|
|
||||||
"""
|
|
||||||
See :attr:`kivymd.uix.behaviors.CommonElevationBehavior.shadow_offset`
|
|
||||||
attribute.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
:attr:`shadow_offset` is an :class:`~kivy.properties.ListProperty`
|
|
||||||
and defaults to `[0, 0]`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
elevation = NumericProperty(0)
|
elevation = NumericProperty(0)
|
||||||
"""
|
"""
|
||||||
See :attr:`kivymd.uix.behaviors.CommonElevationBehavior.elevation`
|
Tab value elevation.
|
||||||
attribute.
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
`Behaviors/Elevation <https://kivymd.readthedocs.io/en/latest/behaviors/elevation/index.html>`_
|
||||||
|
|
||||||
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
:attr:`elevation` is an :class:`~kivy.properties.NumericProperty`
|
||||||
and defaults to `0`.
|
and defaults to `0`.
|
||||||
|
|
|
@ -487,8 +487,6 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
_outer_radius = NumericProperty(0)
|
_outer_radius = NumericProperty(0)
|
||||||
_target_radius = NumericProperty(0)
|
_target_radius = NumericProperty(0)
|
||||||
|
|
||||||
__elevation = 0
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.ripple_max_dist = dp(90)
|
self.ripple_max_dist = dp(90)
|
||||||
self.on_outer_radius(self, self.outer_radius)
|
self.on_outer_radius(self, self.outer_radius)
|
||||||
|
@ -516,89 +514,6 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
if not self.outer_circle_color:
|
if not self.outer_circle_color:
|
||||||
self.outer_circle_color = self.theme_cls.primary_color[:-1]
|
self.outer_circle_color = self.theme_cls.primary_color[:-1]
|
||||||
|
|
||||||
def start(self, *args):
|
|
||||||
"""Starts widget opening animation."""
|
|
||||||
|
|
||||||
self._initialize()
|
|
||||||
self._animate_outer()
|
|
||||||
self.state = "open"
|
|
||||||
self.core_title_text.opacity = 1
|
|
||||||
self.core_description_text.opacity = 1
|
|
||||||
self.dispatch("on_open")
|
|
||||||
|
|
||||||
elevation = getattr(self.widget, "elevation", None)
|
|
||||||
if elevation:
|
|
||||||
self.__elevation = elevation
|
|
||||||
self.widget.elevation = 0
|
|
||||||
|
|
||||||
def stop(self, *args):
|
|
||||||
"""Starts widget close animation."""
|
|
||||||
|
|
||||||
# It needs a better implementation.
|
|
||||||
if self.anim_ripple is not None:
|
|
||||||
self.anim_ripple.unbind(on_complete=self._repeat_ripple)
|
|
||||||
self.core_title_text.opacity = 0
|
|
||||||
self.core_description_text.opacity = 0
|
|
||||||
anim = Animation(
|
|
||||||
d=0.15,
|
|
||||||
t="in_cubic",
|
|
||||||
**dict(
|
|
||||||
zip(
|
|
||||||
["_outer_radius", "_target_radius", "target_ripple_radius"],
|
|
||||||
[0, 0, 0],
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
anim.bind(on_complete=self._after_stop)
|
|
||||||
anim.start(self.widget)
|
|
||||||
|
|
||||||
def on_open(self, *args):
|
|
||||||
"""Called at the time of the start of the widget opening animation."""
|
|
||||||
|
|
||||||
def on_close(self, *args):
|
|
||||||
"""Called at the time of the start of the widget closed animation."""
|
|
||||||
|
|
||||||
def on_draw_shadow(self, instance, value):
|
|
||||||
Logger.warning(
|
|
||||||
"The shadow adding method will be implemented in future versions"
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_description_text(self, instance, value):
|
|
||||||
self.core_description_text.text = value
|
|
||||||
|
|
||||||
def on_description_text_size(self, instance, value):
|
|
||||||
self.core_description_text.font_size = value
|
|
||||||
|
|
||||||
def on_description_text_bold(self, instance, value):
|
|
||||||
self.core_description_text.bold = value
|
|
||||||
|
|
||||||
def on_title_text(self, instance, value):
|
|
||||||
self.core_title_text.text = value
|
|
||||||
|
|
||||||
def on_title_text_size(self, instance, value):
|
|
||||||
self.core_title_text.font_size = value
|
|
||||||
|
|
||||||
def on_title_text_bold(self, instance, value):
|
|
||||||
self.core_title_text.bold = value
|
|
||||||
|
|
||||||
def on_outer_radius(self, instance, value):
|
|
||||||
self._outer_radius = self.outer_radius * 2
|
|
||||||
|
|
||||||
def on_target_radius(self, instance, value):
|
|
||||||
self._target_radius = self.target_radius * 2
|
|
||||||
|
|
||||||
def on_target_touch(self):
|
|
||||||
if self.stop_on_target_touch:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def on_outer_touch(self):
|
|
||||||
if self.stop_on_outer_touch:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def on_outside_click(self):
|
|
||||||
if self.cancelable:
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def _initialize(self):
|
def _initialize(self):
|
||||||
setattr(self.widget, "_outer_radius", 0)
|
setattr(self.widget, "_outer_radius", 0)
|
||||||
setattr(self.widget, "_target_radius", 0)
|
setattr(self.widget, "_target_radius", 0)
|
||||||
|
@ -612,7 +527,7 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
|
|
||||||
def _draw_canvas(self):
|
def _draw_canvas(self):
|
||||||
_pos = self._ttv_pos()
|
_pos = self._ttv_pos()
|
||||||
self.widget.canvas.before.remove_group("ttv_group")
|
self.widget.canvas.before.clear()
|
||||||
|
|
||||||
with self.widget.canvas.before:
|
with self.widget.canvas.before:
|
||||||
# Outer circle.
|
# Outer circle.
|
||||||
|
@ -673,14 +588,34 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
group="ttv_group",
|
group="ttv_group",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def stop(self, *args):
|
||||||
|
"""Starts widget close animation."""
|
||||||
|
|
||||||
|
# It needs a better implementation.
|
||||||
|
if self.anim_ripple is not None:
|
||||||
|
self.anim_ripple.unbind(on_complete=self._repeat_ripple)
|
||||||
|
self.core_title_text.opacity = 0
|
||||||
|
self.core_description_text.opacity = 0
|
||||||
|
anim = Animation(
|
||||||
|
d=0.15,
|
||||||
|
t="in_cubic",
|
||||||
|
**dict(
|
||||||
|
zip(
|
||||||
|
["_outer_radius", "_target_radius", "target_ripple_radius"],
|
||||||
|
[0, 0, 0],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
anim.bind(on_complete=self._after_stop)
|
||||||
|
anim.start(self.widget)
|
||||||
|
|
||||||
def _after_stop(self, *args):
|
def _after_stop(self, *args):
|
||||||
self.widget.canvas.before.remove_group("ttv_group")
|
self.widget.canvas.before.remove_group("ttv_group")
|
||||||
args[0].stop_all(self.widget)
|
args[0].stop_all(self.widget)
|
||||||
|
elev = getattr(self.widget, "elevation", None)
|
||||||
|
|
||||||
elevation = getattr(self.widget, "elevation", None)
|
if elev:
|
||||||
if elevation:
|
self._fix_elev()
|
||||||
self.widget.elevation = self.__elevation
|
|
||||||
|
|
||||||
self.dispatch("on_close")
|
self.dispatch("on_close")
|
||||||
|
|
||||||
# Don't forget to unbind the function or it'll mess
|
# Don't forget to unbind the function or it'll mess
|
||||||
|
@ -704,6 +639,16 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
)
|
)
|
||||||
Color(a=1)
|
Color(a=1)
|
||||||
|
|
||||||
|
def start(self, *args):
|
||||||
|
"""Starts widget opening animation."""
|
||||||
|
|
||||||
|
self._initialize()
|
||||||
|
self._animate_outer()
|
||||||
|
self.state = "open"
|
||||||
|
self.core_title_text.opacity = 1
|
||||||
|
self.core_description_text.opacity = 1
|
||||||
|
self.dispatch("on_open")
|
||||||
|
|
||||||
def _animate_outer(self):
|
def _animate_outer(self):
|
||||||
anim = Animation(
|
anim = Animation(
|
||||||
d=0.2,
|
d=0.2,
|
||||||
|
@ -739,6 +684,53 @@ class MDTapTargetView(ThemableBehavior, EventDispatcher):
|
||||||
setattr(self.widget, "target_ripple_alpha", 1)
|
setattr(self.widget, "target_ripple_alpha", 1)
|
||||||
self._animate_ripple()
|
self._animate_ripple()
|
||||||
|
|
||||||
|
def on_open(self, *args):
|
||||||
|
"""Called at the time of the start of the widget opening animation."""
|
||||||
|
|
||||||
|
def on_close(self, *args):
|
||||||
|
"""Called at the time of the start of the widget closed animation."""
|
||||||
|
|
||||||
|
def on_draw_shadow(self, instance, value):
|
||||||
|
Logger.warning(
|
||||||
|
"The shadow adding method will be implemented in future versions"
|
||||||
|
)
|
||||||
|
|
||||||
|
def on_description_text(self, instance, value):
|
||||||
|
self.core_description_text.text = value
|
||||||
|
|
||||||
|
def on_description_text_size(self, instance, value):
|
||||||
|
self.core_description_text.font_size = value
|
||||||
|
|
||||||
|
def on_description_text_bold(self, instance, value):
|
||||||
|
self.core_description_text.bold = value
|
||||||
|
|
||||||
|
def on_title_text(self, instance, value):
|
||||||
|
self.core_title_text.text = value
|
||||||
|
|
||||||
|
def on_title_text_size(self, instance, value):
|
||||||
|
self.core_title_text.font_size = value
|
||||||
|
|
||||||
|
def on_title_text_bold(self, instance, value):
|
||||||
|
self.core_title_text.bold = value
|
||||||
|
|
||||||
|
def on_outer_radius(self, instance, value):
|
||||||
|
self._outer_radius = self.outer_radius * 2
|
||||||
|
|
||||||
|
def on_target_radius(self, instance, value):
|
||||||
|
self._target_radius = self.target_radius * 2
|
||||||
|
|
||||||
|
def on_target_touch(self):
|
||||||
|
if self.stop_on_target_touch:
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def on_outer_touch(self):
|
||||||
|
if self.stop_on_outer_touch:
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def on_outside_click(self):
|
||||||
|
if self.cancelable:
|
||||||
|
self.stop()
|
||||||
|
|
||||||
def _some_func(self, wid, touch):
|
def _some_func(self, wid, touch):
|
||||||
"""
|
"""
|
||||||
This function decides which one to dispatch based on the touch
|
This function decides which one to dispatch based on the touch
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<RotateWidget>
|
||||||
|
canvas.before:
|
||||||
|
PushMatrix
|
||||||
|
Rotate:
|
||||||
|
angle: self.rotate_value_angle
|
||||||
|
axis: tuple(self.rotate_value_axis)
|
||||||
|
origin: self.center
|
||||||
|
canvas.after:
|
||||||
|
PopMatrix
|
|
@ -2,31 +2,127 @@
|
||||||
Templates/RotateWidget
|
Templates/RotateWidget
|
||||||
======================
|
======================
|
||||||
|
|
||||||
.. deprecated:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
.. note:: `RotateWidget` class has been deprecated. Please use
|
Base class for controlling the rotate of the widget.
|
||||||
`RotateBahavior <https://kivymd.readthedocs.io/en/latest/behaviors/rotate/>`_
|
|
||||||
class instead.
|
.. 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 kivymd.app import MDApp
|
||||||
|
from kivymd.uix.button import MDRaisedButton
|
||||||
|
from kivymd.uix.templates import RotateWidget
|
||||||
|
|
||||||
|
KV = '''
|
||||||
|
MDScreen:
|
||||||
|
|
||||||
|
RotateButton:
|
||||||
|
size_hint: .5, .5
|
||||||
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
on_release: app.change_rotate(self)
|
||||||
|
elevation:0
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class RotateButton(MDRaisedButton, RotateWidget):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Test(MDApp):
|
||||||
|
def build(self):
|
||||||
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
|
def change_rotate(self, instance_button: MDRaisedButton) -> None:
|
||||||
|
Animation(rotate_value_angle=45, d=0.3).start(instance_button)
|
||||||
|
|
||||||
|
|
||||||
|
Test().run()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ("RotateWidget",)
|
__all__ = ("RotateWidget",)
|
||||||
|
|
||||||
from kivy import Logger
|
import os
|
||||||
|
|
||||||
from kivymd.uix.behaviors import RotateBehavior
|
from kivy.lang import Builder
|
||||||
|
from kivy.properties import ListProperty, NumericProperty
|
||||||
|
|
||||||
|
from kivymd import uix_path
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(uix_path, "templates", "rotatewidget", "rotatewidget.kv"),
|
||||||
|
encoding="utf-8",
|
||||||
|
) as kv_file:
|
||||||
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class RotateWidget(RotateBehavior):
|
class RotateWidget:
|
||||||
|
"""Base class for controlling the rotate of the widget."""
|
||||||
|
|
||||||
|
rotate_value_angle = NumericProperty(0)
|
||||||
"""
|
"""
|
||||||
.. deprecated:: 1.1.0
|
Property for getting/setting the angle of the rotation.
|
||||||
Use :class:`~kivymd.uix.behaviors.rotate_behavior.RotateBehavior`
|
|
||||||
class instead.
|
:attr:`rotate_value_angle` is an :class:`~kivy.properties.NumericProperty`
|
||||||
|
and defaults to `0`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
rotate_value_axis = ListProperty((0, 0, 1))
|
||||||
super().__init__(**kwargs)
|
"""
|
||||||
Logger.warning(
|
Property for getting/setting the axis of the rotation.
|
||||||
"KivyMD: "
|
|
||||||
"The `RotateWidget` class has been deprecated. "
|
:attr:`rotate_value_axis` is an :class:`~kivy.properties.NumericProperty`
|
||||||
"Use the `RotateBehavior` class instead."
|
and defaults to `(0, 0, 1)`.
|
||||||
)
|
"""
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<ScaleWidget>
|
||||||
|
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
|
|
@ -2,33 +2,149 @@
|
||||||
Templates/ScaleWidget
|
Templates/ScaleWidget
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
.. deprecated:: 1.1.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
Base class for controlling the scale of the widget.
|
Base class for controlling the scale of the widget.
|
||||||
|
|
||||||
.. note:: `ScaleWidget` class has been deprecated. Please use
|
.. note:: See `kivy.graphics.Scale
|
||||||
`ScaleBehavior <https://kivymd.readthedocs.io/en/latest/behaviors/scale/>`_
|
<https://kivy.org/doc/stable/api-kivy.graphics.html#kivy.graphics.Scale>`_
|
||||||
class instead.
|
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 kivymd.app import MDApp
|
||||||
|
from kivymd.uix.button import MDRaisedButton
|
||||||
|
from kivymd.uix.templates import ScaleWidget
|
||||||
|
|
||||||
|
KV = '''
|
||||||
|
MDScreen:
|
||||||
|
|
||||||
|
ScaleButton:
|
||||||
|
size_hint: .5, .5
|
||||||
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
on_release: app.change_scale(self)
|
||||||
|
elevation:0
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class ScaleButton(MDRaisedButton, ScaleWidget):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Test(MDApp):
|
||||||
|
def build(self):
|
||||||
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
|
def change_scale(self, instance_button: MDRaisedButton) -> 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__ = ("ScaleWidget",)
|
__all__ = ("ScaleWidget",)
|
||||||
|
|
||||||
from kivy import Logger
|
import os
|
||||||
|
|
||||||
from kivymd.uix.behaviors import ScaleBehavior
|
from kivy.lang import Builder
|
||||||
|
from kivy.properties import NumericProperty
|
||||||
|
|
||||||
|
from kivymd import uix_path
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(uix_path, "templates", "scalewidget", "scalewidget.kv"),
|
||||||
|
encoding="utf-8",
|
||||||
|
) as kv_file:
|
||||||
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class ScaleWidget(ScaleBehavior):
|
class ScaleWidget:
|
||||||
|
"""Base class for controlling the scale of the widget."""
|
||||||
|
|
||||||
|
scale_value_x = NumericProperty(1)
|
||||||
"""
|
"""
|
||||||
.. deprecated:: 1.1.0
|
X-axis value.
|
||||||
Use :class:`~kivymd.uix.behaviors.scale_behavior.ScaleBehavior`
|
|
||||||
class instead.
|
:attr:`scale_value_x` is an :class:`~kivy.properties.NumericProperty`
|
||||||
|
and defaults to `1`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
scale_value_y = NumericProperty(1)
|
||||||
super().__init__(**kwargs)
|
"""
|
||||||
Logger.warning(
|
Y-axis value.
|
||||||
"KivyMD: "
|
|
||||||
"The `ScaleWidget` class has been deprecated. "
|
:attr:`scale_value_y` is an :class:`~kivy.properties.NumericProperty`
|
||||||
"Use the `ScaleBehavior` class instead."
|
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`.
|
||||||
|
"""
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<StencilWidget>
|
||||||
|
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
|
|
@ -2,33 +2,115 @@
|
||||||
Templates/StencilWidget
|
Templates/StencilWidget
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
.. deprecated:: 1.1.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
Base class for controlling the stencil instructions of the widget.
|
Base class for controlling the stencil instructions of the widget.
|
||||||
|
|
||||||
.. note:: `StencilWidget` class has been deprecated. Please use
|
.. note:: See `Stencil instructions
|
||||||
`StencilBehavior <https://kivymd.readthedocs.io/en/latest/behaviors/stencil/>`_
|
<https://kivy.org/doc/stable/api-kivy.graphics.stencil_instructions.html>`_
|
||||||
class instead.
|
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.templates import StencilWidget
|
||||||
|
from kivymd.uix.fitimage import FitImage
|
||||||
|
|
||||||
|
KV = '''
|
||||||
|
MDCarousel:
|
||||||
|
|
||||||
|
StencilImage:
|
||||||
|
size_hint: .9, .8
|
||||||
|
pos_hint: {"center_x": .5, "center_y": .5}
|
||||||
|
source: "image.png"
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
class StencilImage(FitImage, StencilWidget):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Test(MDApp):
|
||||||
|
def build(self):
|
||||||
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
|
|
||||||
|
Test().run()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ("StencilWidget",)
|
__all__ = ("StencilWidget",)
|
||||||
|
|
||||||
from kivy import Logger
|
import os
|
||||||
|
|
||||||
from kivymd.uix.behaviors import StencilBehavior
|
from kivy.lang import Builder
|
||||||
|
from kivy.properties import VariableListProperty
|
||||||
|
|
||||||
|
from kivymd import uix_path
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(uix_path, "templates", "stencilwidget", "stencilwidget.kv"),
|
||||||
|
encoding="utf-8",
|
||||||
|
) as kv_file:
|
||||||
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class StencilWidget(StencilBehavior):
|
class StencilWidget:
|
||||||
"""
|
"""Base class for controlling the stencil instructions of the widget"""
|
||||||
.. deprecated:: 1.1.0
|
|
||||||
Use :class:`~kivymd.uix.behaviors.scale_behavior.StencilBehavior`
|
radius = VariableListProperty([0], length=4)
|
||||||
class instead.
|
|
||||||
"""
|
"""
|
||||||
|
Canvas radius.
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
.. versionadded:: 1.0.0
|
||||||
super().__init__(**kwargs)
|
|
||||||
Logger.warning(
|
.. code-block:: python
|
||||||
"KivyMD: "
|
|
||||||
"The `StencilWidget` class has been deprecated. "
|
# Top left corner slice.
|
||||||
"Use the `StencilBehavior` class instead."
|
MDWidget:
|
||||||
)
|
radius: [25, 0, 0, 0]
|
||||||
|
|
||||||
|
:attr:`radius` is an :class:`~kivy.properties.VariableListProperty`
|
||||||
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
|
"""
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
<MDTextField>
|
<MDTextField>
|
||||||
input_filter: self.field_filter
|
|
||||||
do_backspace: self.do_backspace
|
|
||||||
|
|
||||||
canvas.before:
|
canvas.before:
|
||||||
Clear
|
Clear
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ Components/TextField
|
||||||
`KivyMD` provides the following field classes for use:
|
`KivyMD` provides the following field classes for use:
|
||||||
|
|
||||||
- MDTextField_
|
- MDTextField_
|
||||||
|
- MDTextFieldRound_
|
||||||
- MDTextFieldRect_
|
- MDTextFieldRect_
|
||||||
|
|
||||||
.. Note:: :class:`~MDTextField` inherited from
|
.. Note:: :class:`~MDTextField` inherited from
|
||||||
|
@ -78,15 +79,15 @@ parameter to `True`:
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
KV = '''
|
KV = '''
|
||||||
MDScreen:
|
BoxLayout:
|
||||||
|
padding: "10dp"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
id: text_field_error
|
id: text_field_error
|
||||||
hint_text: "Helper text on error (press 'Enter')"
|
hint_text: "Helper text on error (press 'Enter')"
|
||||||
helper_text: "There will always be a mistake"
|
helper_text: "There will always be a mistake"
|
||||||
helper_text_mode: "on_error"
|
helper_text_mode: "on_error"
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
pos_hint: {"center_y": .5}
|
||||||
size_hint_x: .5
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,8 +97,6 @@ parameter to `True`:
|
||||||
self.screen = Builder.load_string(KV)
|
self.screen = Builder.load_string(KV)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
self.screen.ids.text_field_error.bind(
|
self.screen.ids.text_field_error.bind(
|
||||||
on_text_validate=self.set_error_message,
|
on_text_validate=self.set_error_message,
|
||||||
on_focus=self.set_error_message,
|
on_focus=self.set_error_message,
|
||||||
|
@ -120,7 +119,6 @@ Helper text mode `'on_error'` (with required)
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "required = True"
|
hint_text: "required = True"
|
||||||
text: "required = True"
|
|
||||||
required: True
|
required: True
|
||||||
helper_text_mode: "on_error"
|
helper_text_mode: "on_error"
|
||||||
helper_text: "Enter text"
|
helper_text: "Enter text"
|
||||||
|
@ -188,7 +186,7 @@ Round mode
|
||||||
max_text_length: 15
|
max_text_length: 15
|
||||||
helper_text: "Massage"
|
helper_text: "Massage"
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-round-mode.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-round-mode.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
.. MDTextFieldRect:
|
.. MDTextFieldRect:
|
||||||
|
@ -205,7 +203,6 @@ MDTextFieldRect
|
||||||
MDTextFieldRect:
|
MDTextFieldRect:
|
||||||
size_hint: 1, None
|
size_hint: 1, None
|
||||||
height: "30dp"
|
height: "30dp"
|
||||||
background_color: app.theme_cls.bg_normal
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-rect.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-rect.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -281,17 +278,18 @@ __all__ = ("MDTextField", "MDTextFieldRect")
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from datetime import date
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from kivy.animation import Animation
|
from kivy.animation import Animation
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
from kivy.logger import Logger
|
||||||
from kivy.metrics import dp, sp
|
from kivy.metrics import dp, sp
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
AliasProperty,
|
AliasProperty,
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
|
DictProperty,
|
||||||
ListProperty,
|
ListProperty,
|
||||||
NumericProperty,
|
NumericProperty,
|
||||||
ObjectProperty,
|
ObjectProperty,
|
||||||
|
@ -313,220 +311,6 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
# TODO: Add a class to work with the phone number mask.
|
|
||||||
|
|
||||||
|
|
||||||
class AutoFormatTelephoneNumber:
|
|
||||||
"""
|
|
||||||
Implements automatic formatting of the text entered in the text field
|
|
||||||
according to the mask, for example '+38 (###) ### ## ##'.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._backspace = False
|
|
||||||
|
|
||||||
def isnumeric(self, value):
|
|
||||||
try:
|
|
||||||
int(value)
|
|
||||||
return True
|
|
||||||
except ValueError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_backspace(self, *args):
|
|
||||||
if self.validator and self.validator == "phone":
|
|
||||||
self._backspace = True
|
|
||||||
text = self.text
|
|
||||||
text = text[:-1]
|
|
||||||
self.text = text
|
|
||||||
self._backspace = False
|
|
||||||
|
|
||||||
def field_filter(self, value, boolean):
|
|
||||||
if self.validator and self.validator == "phone":
|
|
||||||
if len(self.text) == 14:
|
|
||||||
return
|
|
||||||
if self.isnumeric(value):
|
|
||||||
return value
|
|
||||||
return value
|
|
||||||
|
|
||||||
def format(self, value):
|
|
||||||
if value != "" and not value.isspace() and not self._backspace:
|
|
||||||
if len(value) <= 1 and self.focus:
|
|
||||||
self.text = value
|
|
||||||
self._check_cursor()
|
|
||||||
elif len(value) == 4:
|
|
||||||
start = self.text[:-1]
|
|
||||||
end = self.text[-1]
|
|
||||||
self.text = "%s) %s" % (start, end)
|
|
||||||
self._check_cursor()
|
|
||||||
elif len(value) == 8:
|
|
||||||
self.text += "-"
|
|
||||||
self._check_cursor()
|
|
||||||
elif len(value) in [12, 16]:
|
|
||||||
start = self.text[:-1]
|
|
||||||
end = self.text[-1]
|
|
||||||
self.text = "%s-%s" % (start, end)
|
|
||||||
self._check_cursor()
|
|
||||||
|
|
||||||
def _check_cursor(self):
|
|
||||||
def set_pos_cursor(pos_corsor, interval=0.5):
|
|
||||||
self.cursor = (pos_corsor, 0)
|
|
||||||
|
|
||||||
if self.focus:
|
|
||||||
Clock.schedule_once(lambda x: set_pos_cursor(len(self.text)), 0.1)
|
|
||||||
|
|
||||||
|
|
||||||
class Validator:
|
|
||||||
"""Container class for various validation methods."""
|
|
||||||
|
|
||||||
datetime_date = ObjectProperty()
|
|
||||||
"""
|
|
||||||
The last valid date as a <class 'datetime.date'> object.
|
|
||||||
|
|
||||||
:attr:`datetime_date` is an :class:`~kivy.properties.ObjectProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
date_interval = ListProperty([None, None])
|
|
||||||
"""
|
|
||||||
The date interval that is valid for input.
|
|
||||||
Can be entered as <class 'datetime.date'> objects or a string format.
|
|
||||||
Both values or just one value can be entered.
|
|
||||||
|
|
||||||
In string format, must follow the current date_format.
|
|
||||||
Example: Given date_format -> "mm/dd/yyyy"
|
|
||||||
Input examples -> "12/31/1900", "12/31/2100" or "12/31/1900", None.
|
|
||||||
|
|
||||||
:attr:`date_interval` is an :class:`~kivy.properties.ListProperty`
|
|
||||||
and defaults to `[None, None]`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
date_format = OptionProperty(
|
|
||||||
None,
|
|
||||||
options=[
|
|
||||||
"dd/mm/yyyy",
|
|
||||||
"mm/dd/yyyy",
|
|
||||||
"yyyy/mm/dd",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
"""
|
|
||||||
Format of date strings that will be entered.
|
|
||||||
Available options are: `'dd/mm/yyyy'`, `'mm/dd/yyyy'`, `'yyyy/mm/dd'`.
|
|
||||||
|
|
||||||
:attr:`date_format` is an :class:`~kivy.properties.OptionProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def is_email_valid(self, text: str) -> bool:
|
|
||||||
if not re.match(r"[^@]+@[^@]+\.[^@]+", text):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_time_valid(self, text: str) -> bool:
|
|
||||||
if re.match(r"^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$", text) or re.match(
|
|
||||||
r"^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$", text
|
|
||||||
):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_date_valid(self, text: str) -> bool:
|
|
||||||
if not self.date_format:
|
|
||||||
raise Exception("TextInput date_format was not defined.")
|
|
||||||
|
|
||||||
# Regex strings.
|
|
||||||
dd = "[0][1-9]|[1-2][0-9]|[3][0-1]"
|
|
||||||
mm = "[0][1-9]|[1][0-2]"
|
|
||||||
yyyy = "[0-9][0-9][0-9][0-9]"
|
|
||||||
fmt = self.date_format.split("/")
|
|
||||||
largs = locals()
|
|
||||||
# Access the local variables dict in the correct format based on
|
|
||||||
# date_format split. Example: "mm/dd/yyyy" -> ["mm", "dd", "yyyy"]
|
|
||||||
# largs[fmt[0]] would be largs["mm"] so the month regex string.
|
|
||||||
if re.match(
|
|
||||||
f"^({largs[fmt[0]]})/({largs[fmt[1]]})/({largs[fmt[2]]})$", text
|
|
||||||
):
|
|
||||||
input_split = text.split("/")
|
|
||||||
largs[fmt[0]] = input_split[0]
|
|
||||||
largs[fmt[1]] = input_split[1]
|
|
||||||
largs[fmt[2]] = input_split[2]
|
|
||||||
# Organize input into correct slots and try to convert
|
|
||||||
# to datetime object. This way February exceptions are
|
|
||||||
# tested. Also tests with the date_interval are simpler
|
|
||||||
# using datetime objects.
|
|
||||||
try:
|
|
||||||
datetime = date(
|
|
||||||
int(largs["yyyy"]), int(largs["mm"]), int(largs["dd"])
|
|
||||||
)
|
|
||||||
except ValueError:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if self.date_interval:
|
|
||||||
if (
|
|
||||||
self.date_interval[0]
|
|
||||||
and not self.date_interval[0] <= datetime
|
|
||||||
or self.date_interval[1]
|
|
||||||
and not datetime <= self.date_interval[1]
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
|
|
||||||
self.datetime_date = datetime
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def on_date_interval(self, *args) -> None:
|
|
||||||
"""Default event handler for date_interval input."""
|
|
||||||
|
|
||||||
def on_date_interval():
|
|
||||||
if not self.date_format:
|
|
||||||
raise Exception("TextInput date_format was not defined.")
|
|
||||||
|
|
||||||
fmt = self.date_format.split("/")
|
|
||||||
largs = {}
|
|
||||||
# Convert string inputs into datetime.date objects and store
|
|
||||||
# them back into self.date_interval.
|
|
||||||
try:
|
|
||||||
if self.date_interval[0] and not isinstance(
|
|
||||||
self.date_interval[0], date
|
|
||||||
):
|
|
||||||
split = self.date_interval[0].split("/")
|
|
||||||
largs[fmt[0]] = split[0]
|
|
||||||
largs[fmt[1]] = split[1]
|
|
||||||
largs[fmt[2]] = split[2]
|
|
||||||
self.date_interval[0] = date(
|
|
||||||
int(largs["yyyy"]), int(largs["mm"]), int(largs["dd"])
|
|
||||||
)
|
|
||||||
if self.date_interval[1] and not isinstance(
|
|
||||||
self.date_interval[1], date
|
|
||||||
):
|
|
||||||
split = self.date_interval[1].split("/")
|
|
||||||
largs[fmt[0]] = split[0]
|
|
||||||
largs[fmt[1]] = split[1]
|
|
||||||
largs[fmt[2]] = split[2]
|
|
||||||
self.date_interval[1] = date(
|
|
||||||
int(largs["yyyy"]), int(largs["mm"]), int(largs["dd"])
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
raise Exception(
|
|
||||||
r"TextInput date_interval was defined incorrectly, it must "
|
|
||||||
r"be composed of <class 'datetime.date'> objects or strings"
|
|
||||||
r" following current date_format."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test if the interval is valid.
|
|
||||||
if isinstance(self.date_interval[0], date) and isinstance(
|
|
||||||
self.date_interval[1], date
|
|
||||||
):
|
|
||||||
if self.date_interval[0] >= self.date_interval[1]:
|
|
||||||
raise Exception(
|
|
||||||
"TextInput date_interval last date must be greater"
|
|
||||||
" than the first date or set to None."
|
|
||||||
)
|
|
||||||
|
|
||||||
Clock.schedule_once(lambda x: on_date_interval())
|
|
||||||
|
|
||||||
|
|
||||||
class MDTextFieldRect(ThemableBehavior, TextInput):
|
class MDTextFieldRect(ThemableBehavior, TextInput):
|
||||||
line_anim = BooleanProperty(True)
|
line_anim = BooleanProperty(True)
|
||||||
"""
|
"""
|
||||||
|
@ -599,13 +383,7 @@ class TextfieldLabel(ThemableBehavior, Label):
|
||||||
self.font_size = sp(self.theme_cls.font_styles[self.font_style][1])
|
self.font_size = sp(self.theme_cls.font_styles[self.font_style][1])
|
||||||
|
|
||||||
|
|
||||||
class MDTextField(
|
class MDTextField(DeclarativeBehavior, ThemableBehavior, TextInput):
|
||||||
DeclarativeBehavior,
|
|
||||||
ThemableBehavior,
|
|
||||||
TextInput,
|
|
||||||
Validator,
|
|
||||||
AutoFormatTelephoneNumber,
|
|
||||||
):
|
|
||||||
helper_text = StringProperty()
|
helper_text = StringProperty()
|
||||||
"""
|
"""
|
||||||
Text for ``helper_text`` mode.
|
Text for ``helper_text`` mode.
|
||||||
|
@ -652,185 +430,17 @@ class MDTextField(
|
||||||
and defaults to `'line'`.
|
and defaults to `'line'`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
phone_mask = StringProperty("")
|
|
||||||
|
|
||||||
validator = OptionProperty(None, options=["date", "email", "time", "phone"])
|
|
||||||
"""
|
|
||||||
The type of text field for entering Email, time, etc.
|
|
||||||
Automatically sets the type of the text field as "error" if the user input
|
|
||||||
does not match any of the set validation types.
|
|
||||||
Available options are: `'date'`, `'email'`, `'time'`.
|
|
||||||
|
|
||||||
When using `'date'`, :attr:`date_format` must be defined.
|
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Email"
|
|
||||||
helper_text: "user@gmail.com"
|
|
||||||
validator: "email"
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-validator.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
.. tabs::
|
|
||||||
|
|
||||||
.. tab:: Declarative KV style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivy.lang import Builder
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
|
|
||||||
KV = '''
|
|
||||||
MDScreen:
|
|
||||||
|
|
||||||
MDBoxLayout:
|
|
||||||
orientation: "vertical"
|
|
||||||
spacing: "20dp"
|
|
||||||
adaptive_height: True
|
|
||||||
size_hint_x: .8
|
|
||||||
pos_hint: {"center_x": .5, "center_y": .5}
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date dd/mm/yyyy without limits"
|
|
||||||
helper_text: "Enter a valid dd/mm/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "dd/mm/yyyy"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date mm/dd/yyyy without limits"
|
|
||||||
helper_text: "Enter a valid mm/dd/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "mm/dd/yyyy"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date yyyy/mm/dd without limits"
|
|
||||||
helper_text: "Enter a valid yyyy/mm/dd date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "yyyy/mm/dd"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date dd/mm/yyyy in [01/01/1900, 01/01/2100] interval"
|
|
||||||
helper_text: "Enter a valid dd/mm/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "dd/mm/yyyy"
|
|
||||||
date_interval: "01/01/1900", "01/01/2100"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date dd/mm/yyyy in [01/01/1900, None] interval"
|
|
||||||
helper_text: "Enter a valid dd/mm/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "dd/mm/yyyy"
|
|
||||||
date_interval: "01/01/1900", None
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date dd/mm/yyyy in [None, 01/01/2100] interval"
|
|
||||||
helper_text: "Enter a valid dd/mm/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "dd/mm/yyyy"
|
|
||||||
date_interval: None, "01/01/2100"
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
.. tab:: Declarative python style
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
|
||||||
from kivymd.uix.boxlayout import MDBoxLayout
|
|
||||||
from kivymd.uix.screen import MDScreen
|
|
||||||
from kivymd.uix.textfield import MDTextField
|
|
||||||
|
|
||||||
|
|
||||||
class Test(MDApp):
|
|
||||||
def build(self):
|
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return (
|
|
||||||
MDScreen(
|
|
||||||
MDBoxLayout(
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date dd/mm/yyyy without limits",
|
|
||||||
helper_text="Enter a valid dd/mm/yyyy date",
|
|
||||||
validator="date",
|
|
||||||
date_format="dd/mm/yyyy",
|
|
||||||
),
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date mm/dd/yyyy without limits",
|
|
||||||
helper_text="Enter a valid mm/dd/yyyy date",
|
|
||||||
validator="date",
|
|
||||||
date_format="mm/dd/yyyy",
|
|
||||||
),
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date yyyy/mm/dd without limits",
|
|
||||||
helper_text="Enter a valid yyyy/mm/dd date",
|
|
||||||
validator="date",
|
|
||||||
date_format="yyyy/mm/dd",
|
|
||||||
),
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date dd/mm/yyyy in [01/01/1900, 01/01/2100] interval",
|
|
||||||
helper_text="Enter a valid dd/mm/yyyy date",
|
|
||||||
validator="date",
|
|
||||||
date_format="dd/mm/yyyy",
|
|
||||||
date_interval=["01/01/1900", "01/01/2100"],
|
|
||||||
),
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date dd/mm/yyyy in [01/01/1900, None] interval",
|
|
||||||
helper_text="Enter a valid dd/mm/yyyy date",
|
|
||||||
validator="date",
|
|
||||||
date_format="dd/mm/yyyy",
|
|
||||||
date_interval=["01/01/1900", None],
|
|
||||||
),
|
|
||||||
MDTextField(
|
|
||||||
hint_text="Date dd/mm/yyyy in [None, 01/01/2100] interval",
|
|
||||||
helper_text="Enter a valid dd/mm/yyyy date",
|
|
||||||
validator="date",
|
|
||||||
date_format="dd/mm/yyyy",
|
|
||||||
date_interval=[None, "01/01/2100"],
|
|
||||||
),
|
|
||||||
orientation="vertical",
|
|
||||||
spacing="20dp",
|
|
||||||
adaptive_height=True,
|
|
||||||
size_hint_x=0.8,
|
|
||||||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
Test().run()
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-validator-date.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`validator` is an :class:`~kivy.properties.OptionProperty`
|
|
||||||
and defaults to `None`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
line_color_normal = ColorProperty([0, 0, 0, 0])
|
line_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Line color normal (static underline line) in (r, g, b, a) or string format.
|
Line color normal (static underline line) in ``rgba`` format.
|
||||||
|
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "line_color_normal"
|
hint_text: "line_color_normal"
|
||||||
line_color_normal: "red"
|
line_color_normal: 1, 0, 1, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-line-color-normal.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-line-color-normal.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`line_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`line_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
|
@ -839,13 +449,13 @@ class MDTextField(
|
||||||
|
|
||||||
line_color_focus = ColorProperty([0, 0, 0, 0])
|
line_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Line color focus (active underline line) in (r, g, b, a) or string format.
|
Line color focus (active underline line) in ``rgba`` format.
|
||||||
|
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "line_color_focus"
|
hint_text: "line_color_focus"
|
||||||
line_color_focus: "red"
|
line_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-line-color-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-line-color-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -864,7 +474,7 @@ class MDTextField(
|
||||||
|
|
||||||
error_color = ColorProperty([0, 0, 0, 0])
|
error_color = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Error color in (r, g, b, a) or string format for ``required = True``.
|
Error color in ``rgba`` format for ``required = True``.
|
||||||
|
|
||||||
:attr:`error_color` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`error_color` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `[0, 0, 0, 0]`.
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
|
@ -872,18 +482,7 @@ class MDTextField(
|
||||||
|
|
||||||
fill_color_normal = ColorProperty([0, 0, 0, 0])
|
fill_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Fill background color in (r, g, b, a) or string format in 'fill' mode when]
|
Fill background color in 'fill' mode when text field is out of focus.
|
||||||
text field is out of focus.
|
|
||||||
|
|
||||||
.. code=block:: kv
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Fill mode"
|
|
||||||
mode: "fill"
|
|
||||||
fill_color_normal: "brown"
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-fill-color-normal.png
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`fill_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`fill_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `[0, 0, 0, 0]`.
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
|
@ -891,18 +490,7 @@ class MDTextField(
|
||||||
|
|
||||||
fill_color_focus = ColorProperty([0, 0, 0, 0])
|
fill_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Fill background color in (r, g, b, a) or string format in 'fill' mode when
|
Fill background color in 'fill' mode when the text field has focus.
|
||||||
the text field has focus.
|
|
||||||
|
|
||||||
.. code=block:: kv
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Fill mode"
|
|
||||||
mode: "fill"
|
|
||||||
fill_color_focus: "brown"
|
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-fill-color-focus.gif
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
:attr:`fill_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`fill_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `[0, 0, 0, 0]`.
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
|
@ -926,8 +514,7 @@ class MDTextField(
|
||||||
|
|
||||||
hint_text_color_normal = ColorProperty([0, 0, 0, 0])
|
hint_text_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Hint text color in (r, g, b, a) or string format when text field is out
|
Hint text color when text field is out of focus.
|
||||||
of focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -935,9 +522,9 @@ class MDTextField(
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "hint_text_color_normal"
|
hint_text: "hint_text_color_normal"
|
||||||
hint_text_color_normal: "red"
|
hint_text_color_normal: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-hint-text-color-normal.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-hint-text-color-normal.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`hint_text_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`hint_text_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
|
@ -946,8 +533,7 @@ class MDTextField(
|
||||||
|
|
||||||
hint_text_color_focus = ColorProperty([0, 0, 0, 0])
|
hint_text_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Hint text color in (r, g, b, a) or string format when the text field has
|
Hint text color when the text field has focus.
|
||||||
focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -955,7 +541,7 @@ class MDTextField(
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "hint_text_color_focus"
|
hint_text: "hint_text_color_focus"
|
||||||
hint_text_color_focus: "red"
|
hint_text_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-hint-text-color-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-hint-text-color-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -966,8 +552,7 @@ class MDTextField(
|
||||||
|
|
||||||
helper_text_color_normal = ColorProperty([0, 0, 0, 0])
|
helper_text_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Helper text color in (r, g, b, a) or string format when text field is out
|
Helper text color when text field is out of focus.
|
||||||
of focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -976,7 +561,7 @@ class MDTextField(
|
||||||
MDTextField:
|
MDTextField:
|
||||||
helper_text: "helper_text_color_normal"
|
helper_text: "helper_text_color_normal"
|
||||||
helper_text_mode: "persistent"
|
helper_text_mode: "persistent"
|
||||||
helper_text_color_normal: "red"
|
helper_text_color_normal: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-helper-text-color-normal.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-helper-text-color-normal.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -987,8 +572,7 @@ class MDTextField(
|
||||||
|
|
||||||
helper_text_color_focus = ColorProperty([0, 0, 0, 0])
|
helper_text_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Helper text color in (r, g, b, a) or string format when the text field has
|
Helper text color when the text field has focus.
|
||||||
focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -997,7 +581,7 @@ class MDTextField(
|
||||||
MDTextField:
|
MDTextField:
|
||||||
helper_text: "helper_text_color_focus"
|
helper_text: "helper_text_color_focus"
|
||||||
helper_text_mode: "persistent"
|
helper_text_mode: "persistent"
|
||||||
helper_text_color_focus: "red"
|
helper_text_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-helper-text-color-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-helper-text-color-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -1008,8 +592,7 @@ class MDTextField(
|
||||||
|
|
||||||
icon_right_color_normal = ColorProperty([0, 0, 0, 0])
|
icon_right_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Color in (r, g, b, a) or string format of right icon when text field is out
|
Color of right icon when text field is out of focus.
|
||||||
of focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1018,9 +601,9 @@ class MDTextField(
|
||||||
MDTextField:
|
MDTextField:
|
||||||
icon_right: "language-python"
|
icon_right: "language-python"
|
||||||
hint_text: "icon_right_color_normal"
|
hint_text: "icon_right_color_normal"
|
||||||
icon_right_color_normal: "red"
|
icon_right_color_normal: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-normal.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-normal.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`icon_right_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`icon_right_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
|
@ -1029,8 +612,7 @@ class MDTextField(
|
||||||
|
|
||||||
icon_right_color_focus = ColorProperty([0, 0, 0, 0])
|
icon_right_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Color in (r, g, b, a) or string format of right icon when the text field
|
Color of right icon when the text field has focus.
|
||||||
has focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1039,7 +621,7 @@ class MDTextField(
|
||||||
MDTextField:
|
MDTextField:
|
||||||
icon_right: "language-python"
|
icon_right: "language-python"
|
||||||
hint_text: "icon_right_color_focus"
|
hint_text: "icon_right_color_focus"
|
||||||
icon_right_color_focus: "red"
|
icon_right_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -1050,30 +632,47 @@ class MDTextField(
|
||||||
|
|
||||||
icon_left_color_normal = ColorProperty([0, 0, 0, 0])
|
icon_left_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Color in (r, g, b, a) or string format of right icon when text field is out
|
Color of right icon when text field is out of focus.
|
||||||
of focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
.. code-block:: kv
|
||||||
|
|
||||||
|
MDTextField:
|
||||||
|
icon_right: "language-python"
|
||||||
|
hint_text: "icon_right_color_normal"
|
||||||
|
icon_left_color_normal: 0, 1, 0, 1
|
||||||
|
|
||||||
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-normal.gif
|
||||||
|
:align: center
|
||||||
|
|
||||||
:attr:`icon_left_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`icon_left_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `[0, 0, 0, 0]`.
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
icon_left_color_focus = ColorProperty([0, 0, 0, 0])
|
icon_left_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Color in (r, g, b, a) or string format of right icon when the text field
|
Color of right icon when the text field has focus.
|
||||||
has focus.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
.. code-block:: kv
|
||||||
|
|
||||||
|
MDTextField:
|
||||||
|
icon_right: "language-python"
|
||||||
|
hint_text: "icon_right_color_focus"
|
||||||
|
icon_right_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-icon-right-color-focus.gif
|
||||||
|
:align: center
|
||||||
|
|
||||||
:attr:`icon_left_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`icon_left_color_focus` is an :class:`~kivy.properties.ColorProperty`
|
||||||
and defaults to `[0, 0, 0, 0]`.
|
and defaults to `[0, 0, 0, 0]`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
max_length_text_color = ColorProperty([0, 0, 0, 0])
|
max_length_text_color = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Text color in (r, g, b, a) or string format of the maximum length of
|
Text color of the maximum length of characters to be input.
|
||||||
characters to be input.
|
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1081,10 +680,10 @@ class MDTextField(
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "max_length_text_color"
|
hint_text: "max_length_text_color"
|
||||||
max_length_text_color: "red"
|
max_length_text_color: 0, 1, 0, 1
|
||||||
max_text_length: 5
|
max_text_length: 5
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-max-length-text-color.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-max-length-text-color.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`max_length_text_color` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`max_length_text_color` is an :class:`~kivy.properties.ColorProperty`
|
||||||
|
@ -1119,7 +718,7 @@ class MDTextField(
|
||||||
|
|
||||||
text_color_normal = ColorProperty([0, 0, 0, 0])
|
text_color_normal = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Text color in (r, g, b, a) or string format when text field is out of focus.
|
Text color in ``rgba`` format when text field is out of focus.
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1127,9 +726,9 @@ class MDTextField(
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "text_color_normal"
|
hint_text: "text_color_normal"
|
||||||
text_color_normal: "red"
|
text_color_normal: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-text-color-normal.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-text-color-normal.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
:attr:`text_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
:attr:`text_color_normal` is an :class:`~kivy.properties.ColorProperty`
|
||||||
|
@ -1138,7 +737,7 @@ class MDTextField(
|
||||||
|
|
||||||
text_color_focus = ColorProperty([0, 0, 0, 0])
|
text_color_focus = ColorProperty([0, 0, 0, 0])
|
||||||
"""
|
"""
|
||||||
Text color in (r, g, b, a) or string format when text field has focus.
|
Text color in ``rgba`` format when text field has focus.
|
||||||
|
|
||||||
.. versionadded:: 1.0.0
|
.. versionadded:: 1.0.0
|
||||||
|
|
||||||
|
@ -1146,7 +745,7 @@ class MDTextField(
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "text_color_focus"
|
hint_text: "text_color_focus"
|
||||||
text_color_focus: "red"
|
text_color_focus: 0, 1, 0, 1
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-text-color-focus.gif
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/text-field-text-color-focus.gif
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -1280,8 +879,8 @@ class MDTextField(
|
||||||
text=self.set_text,
|
text=self.set_text,
|
||||||
)
|
)
|
||||||
self.theme_cls.bind(
|
self.theme_cls.bind(
|
||||||
primary_color=self.set_default_colors,
|
primary_color=lambda x, y: self.set_default_colors(0, True),
|
||||||
theme_style=self.set_default_colors,
|
theme_style=lambda x, y: self.set_default_colors(0, True),
|
||||||
)
|
)
|
||||||
Clock.schedule_once(self.check_text)
|
Clock.schedule_once(self.check_text)
|
||||||
|
|
||||||
|
@ -1331,17 +930,9 @@ class MDTextField(
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.error_color == [0, 0, 0, 0] or updated:
|
if self.error_color == [0, 0, 0, 0] or updated:
|
||||||
self.error_color = (
|
self.error_color = self.theme_cls.error_color
|
||||||
self.theme_cls.error_color
|
|
||||||
if self.error_color == [0, 0, 0, 0]
|
|
||||||
else self.error_color
|
|
||||||
)
|
|
||||||
if self.max_length_text_color == [0, 0, 0, 0] or updated:
|
if self.max_length_text_color == [0, 0, 0, 0] or updated:
|
||||||
self.max_length_text_color = (
|
self.max_length_text_color = self.theme_cls.disabled_hint_text_color
|
||||||
self.theme_cls.disabled_hint_text_color
|
|
||||||
if self.max_length_text_color == [0, 0, 0, 0]
|
|
||||||
else self.max_length_text_color
|
|
||||||
)
|
|
||||||
|
|
||||||
self._hint_text_color = self.hint_text_color_normal
|
self._hint_text_color = self.hint_text_color_normal
|
||||||
self._text_color_normal = self.text_color_normal
|
self._text_color_normal = self.text_color_normal
|
||||||
|
@ -1510,11 +1101,8 @@ class MDTextField(
|
||||||
|
|
||||||
self.text = re.sub("\n", " ", text) if not self.multiline else text
|
self.text = re.sub("\n", " ", text) if not self.multiline else text
|
||||||
self.set_max_text_length()
|
self.set_max_text_length()
|
||||||
if self.validator and self.validator == "phone":
|
|
||||||
pass
|
|
||||||
# self.format(self.text)
|
|
||||||
|
|
||||||
if (self.text and self.max_length_text_color) or self._get_has_error():
|
if self.text and self.max_length_text_color and self._get_has_error():
|
||||||
self.error = True
|
self.error = True
|
||||||
if (
|
if (
|
||||||
self.text
|
self.text
|
||||||
|
@ -1713,34 +1301,22 @@ class MDTextField(
|
||||||
if value_height >= self.max_height and self.max_height:
|
if value_height >= self.max_height and self.max_height:
|
||||||
self.height = self.max_height
|
self.height = self.max_height
|
||||||
|
|
||||||
def on_text_color_normal(
|
def on_text_color_normal(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._text_color_normal = color
|
self._text_color_normal = color
|
||||||
|
|
||||||
def on_hint_text_color_normal(
|
def on_hint_text_color_normal(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._hint_text_color = color
|
self._hint_text_color = color
|
||||||
|
|
||||||
def on_helper_text_color_normal(
|
def on_helper_text_color_normal(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._helper_text_color = color
|
self._helper_text_color = color
|
||||||
|
|
||||||
def on_icon_right_color_normal(
|
def on_icon_right_color_normal(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._icon_right_color = color
|
self._icon_right_color = color
|
||||||
|
|
||||||
def on_line_color_normal(
|
def on_line_color_normal(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._line_color_normal = color
|
self._line_color_normal = color
|
||||||
|
|
||||||
def on_max_length_text_color(
|
def on_max_length_text_color(self, instance_text_field, color: list):
|
||||||
self, instance_text_field, color: Union[list, str]
|
|
||||||
):
|
|
||||||
self._max_length_text_color = color
|
self._max_length_text_color = color
|
||||||
|
|
||||||
def _set_color(self, attr_name: str, color: str, updated: bool) -> None:
|
def _set_color(self, attr_name: str, color: str, updated: bool) -> None:
|
||||||
|
@ -1777,13 +1353,6 @@ class MDTextField(
|
||||||
the :attr:`~MDTextField.required` parameter is set to `True`.
|
the :attr:`~MDTextField.required` parameter is set to `True`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.validator and self.validator != "phone":
|
|
||||||
has_error = {
|
|
||||||
"date": self.is_date_valid,
|
|
||||||
"email": self.is_email_valid,
|
|
||||||
"time": self.is_time_valid,
|
|
||||||
}[self.validator](self.text)
|
|
||||||
return has_error
|
|
||||||
if self.max_text_length and len(self.text) > self.max_text_length:
|
if self.max_text_length and len(self.text) > self.max_text_length:
|
||||||
has_error = True
|
has_error = True
|
||||||
else:
|
else:
|
||||||
|
@ -1798,12 +1367,9 @@ class MDTextField(
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from kivy.core.window import Window
|
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.uix.textinput import TextInput
|
from kivy.uix.textinput import TextInput
|
||||||
|
|
||||||
Window.size = (800, 750)
|
|
||||||
|
|
||||||
from kivymd.app import MDApp
|
from kivymd.app import MDApp
|
||||||
|
|
||||||
KV = """
|
KV = """
|
||||||
|
@ -1819,53 +1385,41 @@ MDScreen:
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
mode: "rectangle"
|
mode: "rectangle"
|
||||||
max_text_length: 5
|
max_text_length: 5
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
icon_left: "git"
|
icon_left: "git"
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
mode: "rectangle"
|
mode: "rectangle"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
icon_left: "git"
|
icon_left: "git"
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
mode: "fill"
|
mode: "fill"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
mode: "fill"
|
mode: "fill"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
icon_left: "git"
|
icon_left: "git"
|
||||||
hint_text: "Label"
|
hint_text: "Label"
|
||||||
helper_text: "Error message"
|
helper_text: "Error massage"
|
||||||
|
|
||||||
MDTextField:
|
MDTextField:
|
||||||
hint_text: "Round mode"
|
hint_text: "Round mode"
|
||||||
mode: "round"
|
mode: "round"
|
||||||
max_text_length: 15
|
max_text_length: 15
|
||||||
helper_text: "Message"
|
helper_text: "Massage"
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Date dd/mm/yyyy in [01/01/1900, 01/01/2100] interval"
|
|
||||||
helper_text: "Enter a valid dd/mm/yyyy date"
|
|
||||||
validator: "date"
|
|
||||||
date_format: "dd/mm/yyyy"
|
|
||||||
date_interval: "01/01/1900", "01/01/2100"
|
|
||||||
|
|
||||||
MDTextField:
|
|
||||||
hint_text: "Email"
|
|
||||||
helper_text: "user@gmail.com"
|
|
||||||
validator: "email"
|
|
||||||
|
|
||||||
MDFlatButton:
|
MDFlatButton:
|
||||||
text: "SET TEXT"
|
text: "SET TEXT"
|
||||||
|
@ -1875,8 +1429,6 @@ MDScreen:
|
||||||
|
|
||||||
class Test(MDApp):
|
class Test(MDApp):
|
||||||
def build(self):
|
def build(self):
|
||||||
self.theme_cls.theme_style = "Dark"
|
|
||||||
self.theme_cls.primary_palette = "Orange"
|
|
||||||
return Builder.load_string(KV)
|
return Builder.load_string(KV)
|
||||||
|
|
||||||
def set_text(self):
|
def set_text(self):
|
||||||
|
|
|
@ -121,8 +121,8 @@ Shadow elevation control
|
||||||
.. code-block:: kv
|
.. code-block:: kv
|
||||||
|
|
||||||
MDTopAppBar:
|
MDTopAppBar:
|
||||||
title: "Elevation 4"
|
title: "Elevation 10"
|
||||||
elevation: 4
|
elevation: 10
|
||||||
|
|
||||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toolbar-7.png
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toolbar-7.png
|
||||||
:align: center
|
:align: center
|
||||||
|
@ -327,7 +327,7 @@ Material design 3 style
|
||||||
:align: center
|
:align: center
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ("MDTopAppBar", "MDBottomAppBar", "ActionTopAppBarButton")
|
__all__ = ("MDTopAppBar", "MDBottomAppBar")
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from math import cos, radians, sin
|
from math import cos, radians, sin
|
||||||
|
@ -337,8 +337,10 @@ from kivy.animation import Animation
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
|
from kivy.logger import Logger
|
||||||
from kivy.metrics import dp
|
from kivy.metrics import dp
|
||||||
from kivy.properties import (
|
from kivy.properties import (
|
||||||
|
AliasProperty,
|
||||||
BooleanProperty,
|
BooleanProperty,
|
||||||
ColorProperty,
|
ColorProperty,
|
||||||
ListProperty,
|
ListProperty,
|
||||||
|
@ -354,15 +356,15 @@ from kivymd import uix_path
|
||||||
from kivymd.color_definitions import text_colors
|
from kivymd.color_definitions import text_colors
|
||||||
from kivymd.theming import ThemableBehavior
|
from kivymd.theming import ThemableBehavior
|
||||||
from kivymd.uix.behaviors import (
|
from kivymd.uix.behaviors import (
|
||||||
CommonElevationBehavior,
|
|
||||||
DeclarativeBehavior,
|
DeclarativeBehavior,
|
||||||
ScaleBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
)
|
)
|
||||||
from kivymd.uix.button import MDFloatingActionButton, MDIconButton
|
from kivymd.uix.button import MDFloatingActionButton, MDIconButton
|
||||||
from kivymd.uix.controllers import WindowController
|
from kivymd.uix.controllers import WindowController
|
||||||
from kivymd.uix.list import OneLineIconListItem
|
from kivymd.uix.list import OneLineIconListItem
|
||||||
from kivymd.uix.menu import MDDropdownMenu
|
from kivymd.uix.menu import MDDropdownMenu
|
||||||
|
from kivymd.uix.templates import ScaleWidget
|
||||||
from kivymd.uix.tooltip import MDTooltip
|
from kivymd.uix.tooltip import MDTooltip
|
||||||
from kivymd.utils.set_bars_colors import set_bars_colors
|
from kivymd.utils.set_bars_colors import set_bars_colors
|
||||||
|
|
||||||
|
@ -372,7 +374,7 @@ with open(
|
||||||
Builder.load_string(kv_file.read())
|
Builder.load_string(kv_file.read())
|
||||||
|
|
||||||
|
|
||||||
class ActionBottomAppBarButton(MDFloatingActionButton, ScaleBehavior):
|
class ActionBottomAppBarButton(MDFloatingActionButton, ScaleWidget):
|
||||||
"""
|
"""
|
||||||
Implements a floating action button (FAB) for a toolbar with type 'bottom'.
|
Implements a floating action button (FAB) for a toolbar with type 'bottom'.
|
||||||
"""
|
"""
|
||||||
|
@ -407,11 +409,11 @@ class OverFlowMenuItem(OneLineIconListItem):
|
||||||
|
|
||||||
class NotchedBox(
|
class NotchedBox(
|
||||||
ThemableBehavior,
|
ThemableBehavior,
|
||||||
CommonElevationBehavior,
|
FakeRectangularElevationBehavior,
|
||||||
SpecificBackgroundColorBehavior,
|
SpecificBackgroundColorBehavior,
|
||||||
BoxLayout,
|
BoxLayout,
|
||||||
):
|
):
|
||||||
elevation = NumericProperty(4)
|
elevation = NumericProperty(6)
|
||||||
notch_radius = NumericProperty()
|
notch_radius = NumericProperty()
|
||||||
notch_center_x = NumericProperty("100dp")
|
notch_center_x = NumericProperty("100dp")
|
||||||
|
|
||||||
|
@ -959,10 +961,8 @@ class MDTopAppBar(DeclarativeBehavior, NotchedBox, WindowController):
|
||||||
self.icon_color = self.theme_cls.primary_color
|
self.icon_color = self.theme_cls.primary_color
|
||||||
|
|
||||||
self.bind(specific_text_color=self.update_action_bar_text_colors)
|
self.bind(specific_text_color=self.update_action_bar_text_colors)
|
||||||
self.theme_cls.bind(
|
self.theme_cls.bind(material_style=self.update_bar_height)
|
||||||
material_style=self.update_bar_height,
|
self.theme_cls.bind(primary_palette=self.update_md_bg_color)
|
||||||
primary_palette=self.update_md_bg_color,
|
|
||||||
)
|
|
||||||
|
|
||||||
Clock.schedule_once(
|
Clock.schedule_once(
|
||||||
lambda x: self.on_left_action_items(0, self.left_action_items)
|
lambda x: self.on_left_action_items(0, self.left_action_items)
|
||||||
|
@ -1103,7 +1103,6 @@ class MDTopAppBar(DeclarativeBehavior, NotchedBox, WindowController):
|
||||||
+ self.theme_cls.standard_increment / 2
|
+ self.theme_cls.standard_increment / 2
|
||||||
+ self._shift
|
+ self._shift
|
||||||
)
|
)
|
||||||
self.shadow_offset = [0, 30]
|
|
||||||
self.on_mode(None, self.mode)
|
self.on_mode(None, self.mode)
|
||||||
|
|
||||||
def on_type_height(self, instance_toolbar, height_type_value: str) -> None:
|
def on_type_height(self, instance_toolbar, height_type_value: str) -> None:
|
||||||
|
|
|
@ -314,7 +314,7 @@ class MDTooltip(ThemableBehavior, HoverBehavior, TouchBehavior):
|
||||||
Clock.schedule_once(self.animation_tooltip_dismiss)
|
Clock.schedule_once(self.animation_tooltip_dismiss)
|
||||||
|
|
||||||
def on_show(self) -> None:
|
def on_show(self) -> None:
|
||||||
"""Default display event handler."""
|
"""Default dismiss event handler."""
|
||||||
|
|
||||||
def on_dismiss(self) -> None:
|
def on_dismiss(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -35,9 +35,7 @@ __all__ = (
|
||||||
"MDTransitionBase",
|
"MDTransitionBase",
|
||||||
)
|
)
|
||||||
|
|
||||||
from kivy import Logger
|
|
||||||
from kivy.animation import Animation, AnimationTransition
|
from kivy.animation import Animation, AnimationTransition
|
||||||
from kivy.properties import DictProperty
|
|
||||||
from kivy.uix.screenmanager import (
|
from kivy.uix.screenmanager import (
|
||||||
ScreenManagerException,
|
ScreenManagerException,
|
||||||
SlideTransition,
|
SlideTransition,
|
||||||
|
@ -45,41 +43,13 @@ from kivy.uix.screenmanager import (
|
||||||
TransitionBase,
|
TransitionBase,
|
||||||
)
|
)
|
||||||
|
|
||||||
from kivymd.uix.hero import MDHeroFrom, MDHeroTo
|
|
||||||
from kivymd.uix.screenmanager import MDScreenManager
|
from kivymd.uix.screenmanager import MDScreenManager
|
||||||
|
|
||||||
|
|
||||||
class MDTransitionBase(TransitionBase):
|
class MDTransitionBase(TransitionBase):
|
||||||
"""
|
|
||||||
TransitionBase is used to animate 2 screens within the
|
|
||||||
:class:`~kivymd.uix.screenmanager.MDScreenManager`.
|
|
||||||
|
|
||||||
For more
|
|
||||||
information, see in the :class:`~kivy.uix.screenmanager.TransitionBase`
|
|
||||||
class documentation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
_direction = "in"
|
_direction = "in"
|
||||||
# Collection of child widgets of all 'MDHeroFrom' widgets that are
|
hero_widget = None
|
||||||
# on the screen, for example:
|
hero_from_widget = None # kivymd.uix.hero.MDHeroFrom object
|
||||||
#
|
|
||||||
# MDScreen:
|
|
||||||
#
|
|
||||||
# MDHeroFrom:
|
|
||||||
# tag: "kivymd"
|
|
||||||
#
|
|
||||||
# FitImage:
|
|
||||||
#
|
|
||||||
# MDHeroFrom:
|
|
||||||
# tag: "kivy"
|
|
||||||
#
|
|
||||||
# FitImage:
|
|
||||||
#
|
|
||||||
# {
|
|
||||||
# 'kivy': <kivymd.uix.fitimage.fitimage.FitImage object>,
|
|
||||||
# 'kivymd': <kivymd.uix.fitimage.fitimage.FitImage object>,
|
|
||||||
# }
|
|
||||||
_hero_from_widget_children = DictProperty()
|
|
||||||
|
|
||||||
def start(self, instance_screen_manager: MDScreenManager) -> None:
|
def start(self, instance_screen_manager: MDScreenManager) -> None:
|
||||||
super().start(instance_screen_manager)
|
super().start(instance_screen_manager)
|
||||||
|
@ -89,160 +59,67 @@ class MDTransitionBase(TransitionBase):
|
||||||
]()
|
]()
|
||||||
|
|
||||||
def animated_hero_in(self) -> None:
|
def animated_hero_in(self) -> None:
|
||||||
"""Animates the flight of heroes from screen **A** to screen **B**."""
|
if self.manager._heroes_data and self.manager.current_hero:
|
||||||
|
self.hero_from_widget = self.manager.get_hero_from_widget()
|
||||||
|
self._check_widget_properties()
|
||||||
|
self.hero_widget = self.hero_from_widget.children[0]
|
||||||
|
self.hero_from_widget.remove_widget(self.hero_widget)
|
||||||
|
|
||||||
if self.manager._heroes_data and self.manager.current_heroes:
|
self.hero_widget.pos = self.screen_out.to_widget(
|
||||||
for hero_from_widget in self.manager.get_hero_from_widget():
|
*self.hero_from_widget.to_window(*self.hero_from_widget.pos)
|
||||||
for heroes_tag in self.manager.current_heroes:
|
)
|
||||||
if heroes_tag == hero_from_widget.tag:
|
self.hero_widget.size = self.hero_from_widget.size
|
||||||
self._check_widget_properties(hero_from_widget)
|
self.manager.get_root_window().add_widget(self.hero_widget)
|
||||||
|
|
||||||
# Get child widget of the 'MDHeroFrom' container.
|
Animation(
|
||||||
hero_widget = hero_from_widget.children[0]
|
size=self.screen_in.hero_to.size,
|
||||||
self._hero_from_widget_children[
|
d=self.duration,
|
||||||
hero_from_widget.tag
|
pos=self.screen_in.hero_to.pos,
|
||||||
] = hero_widget
|
).start(self.hero_widget)
|
||||||
|
self.hero_from_widget.dispatch(
|
||||||
# Removing the child widget from the 'MDHeroFrom'
|
"on_transform_in", self.hero_widget, self.duration
|
||||||
# container.
|
)
|
||||||
hero_from_widget.remove_widget(hero_widget)
|
|
||||||
|
|
||||||
# We set the size, position of the child widget of the
|
|
||||||
# 'MDHeroFrom' container and add this widget to the
|
|
||||||
# root window.
|
|
||||||
hero_widget.pos = self.screen_out.to_widget(
|
|
||||||
*hero_from_widget.to_window(*hero_from_widget.pos)
|
|
||||||
)
|
|
||||||
hero_widget.size = hero_from_widget.size
|
|
||||||
self.manager.get_root_window().add_widget(hero_widget)
|
|
||||||
|
|
||||||
# Animating widgets added to the root window.
|
|
||||||
if self.screen_in.heroes_to:
|
|
||||||
for hero_to_widget in self.screen_in.heroes_to:
|
|
||||||
self._check_hero_to_widget_tag(
|
|
||||||
hero_to_widget, hero_from_widget
|
|
||||||
)
|
|
||||||
if hero_to_widget.tag == heroes_tag:
|
|
||||||
Animation(
|
|
||||||
size=hero_to_widget.size,
|
|
||||||
d=self.duration,
|
|
||||||
pos=hero_to_widget.pos,
|
|
||||||
).start(hero_widget)
|
|
||||||
hero_from_widget.dispatch(
|
|
||||||
"on_transform_in",
|
|
||||||
hero_widget,
|
|
||||||
self.duration,
|
|
||||||
)
|
|
||||||
|
|
||||||
def animated_hero_out(self) -> None:
|
def animated_hero_out(self) -> None:
|
||||||
"""Animates the flight of heroes from screen **B** to screen **A**."""
|
if self.manager._heroes_data and self.manager.current_hero:
|
||||||
|
self.screen_out.hero_to.remove_widget(self.hero_widget)
|
||||||
|
self.manager.get_root_window().add_widget(self.hero_widget)
|
||||||
|
|
||||||
if (
|
self.hero_from_widget.dispatch(
|
||||||
self.manager._heroes_data
|
"on_transform_out", self.hero_widget, self.duration
|
||||||
and self.manager.current_heroes
|
)
|
||||||
and self.screen_out.heroes_to
|
Animation(
|
||||||
):
|
pos=self.screen_in.to_widget(
|
||||||
|
*self.hero_from_widget.to_window(*self.hero_from_widget.pos)
|
||||||
for heroes_tag in self.manager.current_heroes:
|
),
|
||||||
for hero_to_widget in self.screen_out.heroes_to:
|
size=self.hero_from_widget.size,
|
||||||
if hero_to_widget.tag == heroes_tag:
|
d=self.duration,
|
||||||
hero_from_children = self._hero_from_widget_children[
|
).start(self.hero_widget)
|
||||||
heroes_tag
|
|
||||||
]
|
|
||||||
hero_to_widget.remove_widget(hero_from_children)
|
|
||||||
self.manager.get_root_window().add_widget(
|
|
||||||
hero_from_children
|
|
||||||
)
|
|
||||||
|
|
||||||
for (
|
|
||||||
hero_from_widget
|
|
||||||
) in self.manager.get_hero_from_widget():
|
|
||||||
hero_from_widget.dispatch(
|
|
||||||
"on_transform_out",
|
|
||||||
self._hero_from_widget_children[
|
|
||||||
hero_from_widget.tag
|
|
||||||
],
|
|
||||||
self.duration,
|
|
||||||
)
|
|
||||||
Animation(
|
|
||||||
pos=self.screen_in.to_widget(
|
|
||||||
*hero_from_widget.to_window(
|
|
||||||
*hero_from_widget.pos
|
|
||||||
)
|
|
||||||
),
|
|
||||||
size=hero_from_widget.size,
|
|
||||||
d=self.duration,
|
|
||||||
).start(
|
|
||||||
self._hero_from_widget_children[
|
|
||||||
hero_from_widget.tag
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_complete(self) -> None:
|
def on_complete(self) -> None:
|
||||||
"""
|
|
||||||
Override method.
|
|
||||||
See :attr:`kivy.uix.screenmanager.TransitionBase.on_complete'.
|
|
||||||
"""
|
|
||||||
|
|
||||||
super().on_complete()
|
super().on_complete()
|
||||||
|
|
||||||
if self.manager._heroes_data and self.manager.current_heroes:
|
|
||||||
for hero_from_widget in self.manager.get_hero_from_widget():
|
|
||||||
for heroes_tag in self.manager.current_heroes:
|
|
||||||
if heroes_tag == hero_from_widget.tag:
|
|
||||||
hero_from_children = self._hero_from_widget_children[
|
|
||||||
heroes_tag
|
|
||||||
]
|
|
||||||
self.manager.get_root_window().remove_widget(
|
|
||||||
hero_from_children
|
|
||||||
)
|
|
||||||
|
|
||||||
# Adding a child widget from the 'MDHeraFrom' container
|
|
||||||
# to the 'MDHeroTo' container.
|
|
||||||
if self._direction == "in":
|
|
||||||
for hero_to_widget in self.screen_in.heroes_to:
|
|
||||||
if hero_to_widget.tag == heroes_tag:
|
|
||||||
hero_to_widget.add_widget(
|
|
||||||
hero_from_children
|
|
||||||
)
|
|
||||||
# Restores the child widget for the 'MDHeraFrom'
|
|
||||||
# container.
|
|
||||||
elif self._direction == "out":
|
|
||||||
hero_from_widget.add_widget(hero_from_children)
|
|
||||||
|
|
||||||
if self._direction == "out":
|
if self._direction == "out":
|
||||||
self._direction = "in"
|
self._direction = "in"
|
||||||
|
if self.manager._heroes_data and self.manager.current_hero:
|
||||||
|
self.manager.get_root_window().remove_widget(self.hero_widget)
|
||||||
|
self.hero_from_widget.add_widget(self.hero_widget)
|
||||||
else:
|
else:
|
||||||
self._direction = "out"
|
self._direction = "out"
|
||||||
|
if self.manager._heroes_data and self.manager.current_hero:
|
||||||
|
self.manager.get_root_window().remove_widget(self.hero_widget)
|
||||||
|
self.screen_in.hero_to.add_widget(self.hero_widget)
|
||||||
|
|
||||||
# Checks the attributes for the 'self.screen_in' screen.
|
def _check_widget_properties(self):
|
||||||
# Called from the animated_hero_in method.
|
if not self.screen_in.hero_to:
|
||||||
def _check_widget_properties(self, hero_from_widget: MDHeroFrom):
|
|
||||||
if not self.screen_in.heroes_to:
|
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"The `heroes_to` attribute is not specified for screen "
|
f"The `hero_to` attribute is not specified for screen {self.screen_in}"
|
||||||
f"{self.screen_in}"
|
|
||||||
)
|
)
|
||||||
# The 'MDHeroFrom' widget allows you to place only one widget in
|
if len(self.hero_from_widget.children) > 1:
|
||||||
# itself.
|
|
||||||
if len(hero_from_widget.children) > 1:
|
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"{hero_from_widget.__class__} accept only one widget"
|
f"{self.hero_from_widget.__class__} accept only one widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
# For new API support.
|
|
||||||
def _check_hero_to_widget_tag(
|
|
||||||
self, hero_to_widget: MDHeroTo, hero_from_widget: MDHeroFrom
|
|
||||||
) -> None:
|
|
||||||
if not hero_to_widget.tag:
|
|
||||||
Logger.warning(
|
|
||||||
"KivyMD: "
|
|
||||||
f"Set the tag '{hero_from_widget.tag}' "
|
|
||||||
f"for the {hero_to_widget} widget to the same "
|
|
||||||
f"as for the {hero_from_widget} widget"
|
|
||||||
)
|
|
||||||
hero_to_widget.tag = hero_from_widget.tag
|
|
||||||
|
|
||||||
|
|
||||||
class MDSwapTransition(SwapTransition, MDTransitionBase):
|
class MDSwapTransition(SwapTransition, MDTransitionBase):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -36,13 +36,11 @@ MDWidget
|
||||||
|
|
||||||
__all__ = ("MDWidget",)
|
__all__ = ("MDWidget",)
|
||||||
|
|
||||||
from kivy.uix.widget import Widget
|
|
||||||
|
|
||||||
from kivymd.uix import MDAdaptiveWidget
|
from kivymd.uix import MDAdaptiveWidget
|
||||||
from kivymd.uix.behaviors import DeclarativeBehavior
|
from kivymd.uix.behaviors import DeclarativeBehavior
|
||||||
|
|
||||||
|
|
||||||
class MDWidget(DeclarativeBehavior, MDAdaptiveWidget, Widget):
|
class MDWidget(DeclarativeBehavior, MDAdaptiveWidget):
|
||||||
"""
|
"""
|
||||||
See :class:`~kivy.uix.Widget` class documentation for more information.
|
See :class:`~kivy.uix.Widget` class documentation for more information.
|
||||||
|
|
||||||
|
|