working condition

This commit is contained in:
Yura 2024-09-15 20:57:02 +03:00
parent 417e54da96
commit 511e0b0379
517 changed files with 29187 additions and 32696 deletions

View file

@ -26,12 +26,10 @@ import os
import kivy
from kivy.logger import Logger
__version__ = "1.2.0"
"""KivyMD version."""
from kivymd._version import __version__, release
release = False
if "READTHEDOCS" not in os.environ:
kivy.require("2.2.0")
kivy.require("2.3.0")
try:
from kivymd._version import __date__, __hash__, __short_hash__
@ -59,13 +57,8 @@ _log_message = (
+ f' (installed at "{__file__}")'
)
Logger.info(_log_message)
Logger.warning(
"KivyMD: "
"Version 1.2.0 is deprecated and is no longer supported. "
"Use KivyMD version 2.0.0 from the master branch "
"(pip install https://github.com/kivymd/KivyMD/archive/master.zip)"
)
import kivymd.factory_registers # NOQA
import kivymd.font_definitions # NOQA
import kivymd.animation # NOQA
from kivymd.tools.packaging.pyinstaller import hooks_path # NOQA

View file

@ -1,5 +1,5 @@
# THIS FILE IS GENERATED FROM KIVYMD SETUP.PY
__version__ = '1.2.0'
__hash__ = 'Unknown'
__short_hash__ = 'Unknown'
__date__ = '2024-09-15'
release = False
__version__ = "2.0.1.dev0"
__hash__ = "Unknown"
__short_hash__ = "Unknown"
__date__ = "2024-09-15"

View file

@ -0,0 +1,224 @@
"""
Animation
=========
.. versionadded:: 2.0.0
Adds new transitions to the :class:`~kivy.animation.AnimationTransition` class:
- "easing_standard"
- "easing_decelerated"
- "easing_accelerated"
- "easing_linear"
.. code-block:: python
from kivy.lang import Builder
from kivy.animation import Animation
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.metrics import dp
from kivy.properties import ListProperty
from kivymd.app import MDApp
class AnimBox(BoxLayout):
obj_pos = ListProperty([0, 0])
UI = '''
<AnimBox>:
transition:"in_out_bounce"
size_hint_y:None
height:dp(100)
obj_pos:[dp(40), self.pos[-1] + dp(40)]
canvas:
Color:
rgba:app.theme_cls.primaryContainerColor
Rectangle:
size:[self.size[0], dp(5)]
pos:self.pos[0], self.pos[-1] + dp(50)
Color:
rgba:app.theme_cls.primaryColor
Rectangle:
size:[dp(30)] * 2
pos:root.obj_pos
MDLabel:
adaptive_height:True
text:root.transition
padding:[dp(10), 0]
halign:"center"
MDGridLayout:
orientation:"lr-tb"
cols:1
md_bg_color:app.theme_cls.backgroundColor
spacing:dp(10)
'''
class MotionApp(MDApp):
def build(self):
return Builder.load_string(UI)
def on_start(self):
for transition in [
"easing_linear",
"easing_accelerated",
"easing_decelerated",
"easing_standard",
"in_out_cubic"
]: # Add more here for comparison
print(transition)
widget = AnimBox()
widget.transition = transition
self.root.add_widget(widget)
Clock.schedule_once(self.run_animation, 1)
_inverse = True
def run_animation(self, dt):
x = (self.root.children[0].width - dp(30)) if self._inverse else 0
for widget in self.root.children:
Animation(
obj_pos=[x, widget.obj_pos[-1]], t=widget.transition, d=3
).start(widget)
self._inverse = not self._inverse
Clock.schedule_once(self.run_animation, 3.1)
MotionApp().run()
.. image:: https://github.com/kivymd/KivyMD/assets/68729523/21c847b0-284a-4796-b704-e4a2531fbb1b
:align: center
"""
import math
import sys
import kivy.animation
float_epsilon = 8.3446500e-7
if sys.version_info < (3, 11):
cbrt = lambda number: (abs(number) ** (1/3)) * (-1 if number < 0 else 1)
else:
cbrt = math.cbrt
class CubicBezier:
"""Ported from Android source code"""
p0 = 0
p1 = 0
p2 = 0
p3 = 0
def __init__(self, *args):
self.p0, self.p1, self.p2, self.p3 = args
def evaluate_cubic(self, p1, p2, t):
a = 1.0 / 3.0 + (p1 - p2)
b = p2 - 2.0 * p1
c = p1
return 3.0 * ((a * t + b) * t + c) * t
def clamp_range(self, r):
if r < 0.0:
if -float_epsilon <= r < 0.0:
return 0.0
else:
return math.nan
elif r > 1.0:
if 1.0 <= r <= 1.0 + float_epsilon:
return 1.0
else:
return math.nan
else:
return r
def close_to(self, x, y):
return abs(x - y) < float_epsilon
def find_first_cubic_root(self, p0, p1, p2, p3):
a = 3.0 * (p0 - 2.0 * p1 + p2)
b = 3.0 * (p1 - p0)
c = p0
d = -p0 + 3.0 * (p1 - p2) + p3
if self.close_to(d, 0.0):
if self.close_to(a, 0.0):
if self.close_to(b, 0.0):
return math.nan
return self.clamp_range(-c / b)
else:
q = math.sqrt(b * b - 4.0 * a * c)
a2 = 2.0 * a
root = self.clamp_range((q - b) / a2)
if not math.isnan(root):
return root
return self.clamp_range((-b - q) / a2)
a /= d
b /= d
c /= d
o3 = (3.0 * b - a * a) / 9.0
q2 = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0
discriminant = q2 * q2 + o3 * o3 * o3
a3 = a / 3.0
if discriminant < 0.0:
mp33 = -(o3 * o3 * o3)
r = math.sqrt(mp33)
t = -q2 / r
cos_phi = max(-1.0, min(t, 1.0))
phi = math.acos(cos_phi)
t1 = 2.0 * cbrt(r)
root = self.clamp_range(t1 * math.cos(phi / 3.0) - a3)
if not math.isnan(root):
return root
root = self.clamp_range(
t1 * math.cos((phi + 2.0 * math.pi) / 3.0) - a3
)
if not math.isnan(root):
return root
return self.clamp_range(
t1 * math.cos((phi + 4.0 * math.pi) / 3.0) - a3
)
elif self.close_to(discriminant, 0.0):
u1 = -cbrt(q2)
root = self.clamp_range(2.0 * u1 - a3)
if not math.isnan(root):
return root
return self.clamp_range(-u1 - a3)
sd = math.sqrt(discriminant)
u1 = cbrt(-q2 + sd)
v1 = cbrt(q2 + sd)
return self.clamp_range(u1 - v1 - a3)
def t(self, value: float):
return self.evaluate_cubic(
self.p1,
self.p3,
self.find_first_cubic_root(
-value,
self.p0 - value,
self.p2 - value,
1.0 - value,
),
)
class MDAnimationTransition(kivy.animation.AnimationTransition):
"""KivyMD's equivalent of kivy's `AnimationTransition`"""
easing_standard = CubicBezier(0.4, 0.0, 0.2, 1.0).t
easing_decelerated = CubicBezier(0.0, 0.0, 0.2, 1.0).t
easing_accelerated = CubicBezier(0.4, 0.0, 1.0, 1.0).t
easing_linear = CubicBezier(0.0, 0.0, 1.0, 1.0).t
# TODO: add `easing_emphasized` here
# it's defination is
# path(M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1)
# Monkey patch kivy's animation module
kivy.animation.AnimationTransition = MDAnimationTransition

View file

@ -3,14 +3,15 @@ Themes/Material App
===================
This module contains :class:`MDApp` class that is inherited from
:class:`~kivy.app.App`. :class:`MDApp` has some properties needed for ``KivyMD``
library (like :attr:`~MDApp.theme_cls`). You can turn on the monitor displaying
the current ``FPS`` value in your application:
:class:`~kivy.app.App`. :class:`MDApp` has some properties needed for `KivyMD`
library (like :attr:`~MDApp.theme_cls`). You can turn on the monitor
displaying the current `FP` value in your application:
.. code-block:: python
KV = '''
MDScreen:
md_bg_color: self.theme_cls.backgroundColor
MDLabel:
text: "Hello, World!"
@ -32,10 +33,23 @@ the current ``FPS`` value in your application:
MainApp().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fps-monitor.png
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fps-monitor-dark.png
:width: 350 px
:align: center
.. note::
Note that if you override the built-in on_start method, you will
definitely need to call the super method:
.. code-block:: python
class MainApp(MDApp):
def build(self):
[...]
def on_start(self):
[...]
"""
__all__ = ("MDApp",)
@ -55,7 +69,12 @@ class FpsMonitoring:
"""Implements a monitor to display the current FPS in the toolbar."""
def fps_monitor_start(self, anchor: str = "top") -> None:
"""Adds a monitor to the main application window."""
"""
Adds a monitor to the main application window.
:type anchor: str;
:param anchor: anchor FPS panel ('top' or 'bottom');
"""
def add_monitor(*args):
from kivy.core.window import Window
@ -114,6 +133,14 @@ class MDApp(App, FpsMonitoring):
super().__init__(**kwargs)
self.theme_cls = ThemeManager()
def _run_prepare(self):
self.theme_cls.bind(
theme_style=self.theme_cls.update_theme_colors,
primary_palette=self.theme_cls.set_colors
)
self.theme_cls.set_colors()
super()._run_prepare()
def load_all_kv_files(self, path_to_directory: str) -> None:
"""
Recursively loads KV files from the selected directory.
@ -128,8 +155,8 @@ class MDApp(App, FpsMonitoring):
if "kivymd" in path_to_directory:
Logger.critical(
"KivyMD: "
"Do not use the word 'kivymd' in the name of the directory "
"from where you download KV files"
"Do not use the word 'kivymd' in the name of the "
"directory from where you download KV files"
)
if (
"venv" in path_to_dir

View file

@ -1,954 +0,0 @@
"""
Themes/Color Definitions
========================
.. seealso::
`Material Design spec, The color system <https://material.io/design/color/the-color-system.html>`_
`Material Design spec, The color tool <https://material.io/resources/color/#!/?view.left=0&view.right=0>`_
Material colors palette to use in :class:`kivymd.theming.ThemeManager`.
:data:`~colors` is a dict-in-dict where the first key is a value from
:data:`~palette` and the second key is a value from :data:`~hue`. Color is a hex
value, a string of 6 characters (0-9, A-F) written in uppercase.
For example, ``colors["Red"]["900"]`` is ``"B71C1C"``.
"""
colors = {
"Red": {
"50": "FFEBEE",
"100": "FFCDD2",
"200": "EF9A9A",
"300": "E57373",
"400": "EF5350",
"500": "F44336",
"600": "E53935",
"700": "D32F2F",
"800": "C62828",
"900": "B71C1C",
"A100": "FF8A80",
"A200": "FF5252",
"A400": "FF1744",
"A700": "D50000",
},
"Pink": {
"50": "FCE4EC",
"100": "F8BBD0",
"200": "F48FB1",
"300": "F06292",
"400": "EC407A",
"500": "E91E63",
"600": "D81B60",
"700": "C2185B",
"800": "AD1457",
"900": "880E4F",
"A100": "FF80AB",
"A200": "FF4081",
"A400": "F50057",
"A700": "C51162",
},
"Purple": {
"50": "F3E5F5",
"100": "E1BEE7",
"200": "CE93D8",
"300": "BA68C8",
"400": "AB47BC",
"500": "9C27B0",
"600": "8E24AA",
"700": "7B1FA2",
"800": "6A1B9A",
"900": "4A148C",
"A100": "EA80FC",
"A200": "E040FB",
"A400": "D500F9",
"A700": "AA00FF",
},
"DeepPurple": {
"50": "EDE7F6",
"100": "D1C4E9",
"200": "B39DDB",
"300": "9575CD",
"400": "7E57C2",
"500": "673AB7",
"600": "5E35B1",
"700": "512DA8",
"800": "4527A0",
"900": "311B92",
"A100": "B388FF",
"A200": "7C4DFF",
"A400": "651FFF",
"A700": "6200EA",
},
"Indigo": {
"50": "E8EAF6",
"100": "C5CAE9",
"200": "9FA8DA",
"300": "7986CB",
"400": "5C6BC0",
"500": "3F51B5",
"600": "3949AB",
"700": "303F9F",
"800": "283593",
"900": "1A237E",
"A100": "8C9EFF",
"A200": "536DFE",
"A400": "3D5AFE",
"A700": "304FFE",
},
"Blue": {
"50": "E3F2FD",
"100": "BBDEFB",
"200": "90CAF9",
"300": "64B5F6",
"400": "42A5F5",
"500": "2196F3",
"600": "1E88E5",
"700": "1976D2",
"800": "1565C0",
"900": "0D47A1",
"A100": "82B1FF",
"A200": "448AFF",
"A400": "2979FF",
"A700": "2962FF",
},
"LightBlue": {
"50": "E1F5FE",
"100": "B3E5FC",
"200": "81D4FA",
"300": "4FC3F7",
"400": "29B6F6",
"500": "03A9F4",
"600": "039BE5",
"700": "0288D1",
"800": "0277BD",
"900": "01579B",
"A100": "80D8FF",
"A200": "40C4FF",
"A400": "00B0FF",
"A700": "0091EA",
},
"Cyan": {
"50": "E0F7FA",
"100": "B2EBF2",
"200": "80DEEA",
"300": "4DD0E1",
"400": "26C6DA",
"500": "00BCD4",
"600": "00ACC1",
"700": "0097A7",
"800": "00838F",
"900": "006064",
"A100": "84FFFF",
"A200": "18FFFF",
"A400": "00E5FF",
"A700": "00B8D4",
},
"Teal": {
"50": "E0F2F1",
"100": "B2DFDB",
"200": "80CBC4",
"300": "4DB6AC",
"400": "26A69A",
"500": "009688",
"600": "00897B",
"700": "00796B",
"800": "00695C",
"900": "004D40",
"A100": "A7FFEB",
"A200": "64FFDA",
"A400": "1DE9B6",
"A700": "00BFA5",
},
"Green": {
"50": "E8F5E9",
"100": "C8E6C9",
"200": "A5D6A7",
"300": "81C784",
"400": "66BB6A",
"500": "4CAF50",
"600": "43A047",
"700": "388E3C",
"800": "2E7D32",
"900": "1B5E20",
"A100": "B9F6CA",
"A200": "69F0AE",
"A400": "00E676",
"A700": "00C853",
},
"LightGreen": {
"50": "F1F8E9",
"100": "DCEDC8",
"200": "C5E1A5",
"300": "AED581",
"400": "9CCC65",
"500": "8BC34A",
"600": "7CB342",
"700": "689F38",
"800": "558B2F",
"900": "33691E",
"A100": "CCFF90",
"A200": "B2FF59",
"A400": "76FF03",
"A700": "64DD17",
},
"Lime": {
"50": "F9FBE7",
"100": "F0F4C3",
"200": "E6EE9C",
"300": "DCE775",
"400": "D4E157",
"500": "CDDC39",
"600": "C0CA33",
"700": "AFB42B",
"800": "9E9D24",
"900": "827717",
"A100": "F4FF81",
"A200": "EEFF41",
"A400": "C6FF00",
"A700": "AEEA00",
},
"Yellow": {
"50": "FFFDE7",
"100": "FFF9C4",
"200": "FFF59D",
"300": "FFF176",
"400": "FFEE58",
"500": "FFEB3B",
"600": "FDD835",
"700": "FBC02D",
"800": "F9A825",
"900": "F57F17",
"A100": "FFFF8D",
"A200": "FFFF00",
"A400": "FFEA00",
"A700": "FFD600",
},
"Amber": {
"50": "FFF8E1",
"100": "FFECB3",
"200": "FFE082",
"300": "FFD54F",
"400": "FFCA28",
"500": "FFC107",
"600": "FFB300",
"700": "FFA000",
"800": "FF8F00",
"900": "FF6F00",
"A100": "FFE57F",
"A200": "FFD740",
"A400": "FFC400",
"A700": "FFAB00",
},
"Orange": {
"50": "FFF3E0",
"100": "FFE0B2",
"200": "FFCC80",
"300": "FFB74D",
"400": "FFA726",
"500": "FF9800",
"600": "FB8C00",
"700": "F57C00",
"800": "EF6C00",
"900": "E65100",
"A100": "FFD180",
"A200": "FFAB40",
"A400": "FF9100",
"A700": "FF6D00",
},
"DeepOrange": {
"50": "FBE9E7",
"100": "FFCCBC",
"200": "FFAB91",
"300": "FF8A65",
"400": "FF7043",
"500": "FF5722",
"600": "F4511E",
"700": "E64A19",
"800": "D84315",
"900": "BF360C",
"A100": "FF9E80",
"A200": "FF6E40",
"A400": "FF3D00",
"A700": "DD2C00",
},
"Brown": {
"50": "EFEBE9",
"100": "D7CCC8",
"200": "BCAAA4",
"300": "A1887F",
"400": "8D6E63",
"500": "795548",
"600": "6D4C41",
"700": "5D4037",
"800": "4E342E",
"900": "3E2723",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Gray": {
"50": "FAFAFA",
"100": "F5F5F5",
"200": "EEEEEE",
"300": "E0E0E0",
"400": "BDBDBD",
"500": "9E9E9E",
"600": "757575",
"700": "616161",
"800": "424242",
"900": "212121",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"BlueGray": {
"50": "ECEFF1",
"100": "CFD8DC",
"200": "B0BEC5",
"300": "90A4AE",
"400": "78909C",
"500": "607D8B",
"600": "546E7A",
"700": "455A64",
"800": "37474F",
"900": "263238",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Light": {
"StatusBar": "E0E0E0",
"AppBar": "F5F5F5",
"Background": "FAFAFA",
"CardsDialogs": "FFFFFF",
"FlatButtonDown": "cccccc",
},
"Dark": {
"StatusBar": "000000",
"AppBar": "1f1f1f",
"Background": "121212",
"CardsDialogs": "212121",
"FlatButtonDown": "999999",
},
}
"""
Color palette. Taken from `2014 Material Design color palettes
<https://material.io/design/color/the-color-system.html>`_.
To demonstrate the shades of the palette, you can run the following code:
.. code-block:: python
from kivy.lang import Builder
from kivy.properties import ListProperty, StringProperty
from kivymd.color_definitions import colors
from kivymd.uix.tab import MDTabsBase
from kivymd.uix.boxlayout import MDBoxLayout
demo = '''
<Root@MDBoxLayout>
orientation: 'vertical'
MDTopAppBar:
title: app.title
MDTabs:
id: android_tabs
on_tab_switch: app.on_tab_switch(*args)
size_hint_y: None
height: "48dp"
tab_indicator_anim: False
RecycleView:
id: rv
key_viewclass: "viewclass"
key_size: "height"
RecycleBoxLayout:
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: "vertical"
<ItemColor>
size_hint_y: None
height: "42dp"
MDLabel:
text: root.text
halign: "center"
<Tab>
'''
from kivy.factory import Factory
from kivymd.app import MDApp
class Tab(MDBoxLayout, MDTabsBase):
pass
class ItemColor(MDBoxLayout):
text = StringProperty()
color = ListProperty()
class Palette(MDApp):
title = "Colors definitions"
def build(self):
Builder.load_string(demo)
self.screen = Factory.Root()
for name_tab in colors.keys():
tab = Tab(title=name_tab)
self.screen.ids.android_tabs.add_widget(tab)
return self.screen
def on_tab_switch(
self, instance_tabs, instance_tab, instance_tabs_label, tab_text
):
self.screen.ids.rv.data = []
if not tab_text:
tab_text = 'Red'
for value_color in colors[tab_text]:
self.screen.ids.rv.data.append(
{
"viewclass": "ItemColor",
"md_bg_color": colors[tab_text][value_color],
"title": value_color,
}
)
def on_start(self):
self.on_tab_switch(
None,
None,
None,
self.screen.ids.android_tabs.ids.layout.children[-1].text,
)
Palette().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/palette.gif
:align: center
"""
palette = [
"Red",
"Pink",
"Purple",
"DeepPurple",
"Indigo",
"Blue",
"LightBlue",
"Cyan",
"Teal",
"Green",
"LightGreen",
"Lime",
"Yellow",
"Amber",
"Orange",
"DeepOrange",
"Brown",
"Gray",
"BlueGray",
]
"""Valid values for color palette selecting."""
hue = [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"700",
"800",
"900",
"A100",
"A200",
"A400",
"A700",
]
"""Valid values for color hue selecting."""
light_colors = {
"Red": ["50", "100", "200", "300", "A100"],
"Pink": ["50", "100", "200", "A100"],
"Purple": ["50", "100", "200", "A100"],
"DeepPurple": ["50", "100", "200", "A100"],
"Indigo": ["50", "100", "200", "A100"],
"Blue": ["50", "100", "200", "300", "400", "A100"],
"LightBlue": [
"50",
"100",
"200",
"300",
"400",
"500",
"A100",
"A200",
"A400",
],
"Cyan": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"A100",
"A200",
"A400",
"A700",
],
"Teal": ["50", "100", "200", "300", "400", "A100", "A200", "A400", "A700"],
"Green": [
"50",
"100",
"200",
"300",
"400",
"500",
"A100",
"A200",
"A400",
"A700",
],
"LightGreen": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"A100",
"A200",
"A400",
"A700",
],
"Lime": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"700",
"800",
"A100",
"A200",
"A400",
"A700",
],
"Yellow": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"700",
"800",
"900",
"A100",
"A200",
"A400",
"A700",
],
"Amber": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"700",
"800",
"900",
"A100",
"A200",
"A400",
"A700",
],
"Orange": [
"50",
"100",
"200",
"300",
"400",
"500",
"600",
"700",
"A100",
"A200",
"A400",
"A700",
],
"DeepOrange": ["50", "100", "200", "300", "400", "A100", "A200"],
"Brown": ["50", "100", "200"],
"Gray": ["50", "100", "200", "300", "400", "500"],
"BlueGray": ["50", "100", "200", "300"],
"Dark": [],
"Light": ["White", "MainBackground", "DialogBackground"],
}
"""Which colors are light. Other are dark."""
text_colors = {
"Red": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Pink": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "FFFFFF",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Purple": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "FFFFFF",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"DeepPurple": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "FFFFFF",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Indigo": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "FFFFFF",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Blue": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"LightBlue": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "FFFFFF",
},
"Cyan": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Teal": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Green": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"LightGreen": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Lime": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "000000",
"800": "000000",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Yellow": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "000000",
"800": "000000",
"900": "000000",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Amber": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "000000",
"800": "000000",
"900": "000000",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"Orange": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "000000",
"700": "000000",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "000000",
"A700": "000000",
},
"DeepOrange": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "000000",
"A200": "000000",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Brown": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "FFFFFF",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "FFFFFF",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"Gray": {
"50": "FFFFFF",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "000000",
"500": "000000",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "FFFFFF",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
"BlueGray": {
"50": "000000",
"100": "000000",
"200": "000000",
"300": "000000",
"400": "FFFFFF",
"500": "FFFFFF",
"600": "FFFFFF",
"700": "FFFFFF",
"800": "FFFFFF",
"900": "FFFFFF",
"A100": "FFFFFF",
"A200": "FFFFFF",
"A400": "FFFFFF",
"A700": "FFFFFF",
},
}
"""
Text colors generated from :data:`~light_colors`. "000000" for light and
"FFFFFF" for dark.
How to generate text_colors dict
.. code-block:: python
text_colors = {}
for p in palette:
text_colors[p] = {}
for h in hue:
if h in light_colors[p]:
text_colors[p][h] = "000000"
else:
text_colors[p][h] = "FFFFFF"
"""
theme_colors = [
"Primary",
"Secondary",
"Background",
"Surface",
"Error",
"On_Primary",
"On_Secondary",
"On_Background",
"On_Surface",
"On_Error",
]
"""Valid theme colors."""

View file

@ -0,0 +1,632 @@
"""
Components/Dynamic color
========================
.. seealso::
`Material Design spec, Dynamic color
<https://m3.material.io/styles/color/dynamic-color/overview>`_
.. rubric:: Dynamic color can create accessible UI color schemes based on
content or user settings
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color.png
:align: center
Dynamic color experiences are built with M3 color schemes. Beginning with
Android 12, users can generate individualized schemes through wallpaper
selection and other customization settings. With M3 as a foundation,
user-generated colors can coexist with app colors, putting a range of
customizable visual experiences in the hands of users.
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color-preview.png
:align: center
1. Baseline scheme
2. Colors extracted from a wallpaper
3. Colors extracted from content
Example of dynamic color from the list of standard color schemes
----------------------------------------------------------------
.. code-block:: python
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty, ColorProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.utils import hex_colormap
from kivymd.uix.menu import MDDropdownMenu
from kivymd.app import MDApp
KV = '''
<ColorCard>
orientation: "vertical"
MDLabel:
text: root.text
color: "grey"
adaptive_height: True
MDCard:
theme_bg_color: "Custom"
md_bg_color: root.bg_color
MDScreen:
md_bg_color: app.theme_cls.backgroundColor
MDIconButton:
on_release: app.open_menu(self)
pos_hint: {"top": .98}
x: "12dp"
icon: "menu"
MDRecycleView:
id: card_list
viewclass: "ColorCard"
bar_width: 0
size_hint_y: None
height: root.height - dp(68)
RecycleGridLayout:
cols: 3
spacing: "16dp"
padding: "16dp"
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
'''
class ColorCard(BoxLayout):
text = StringProperty()
bg_color = ColorProperty()
class Example(MDApp):
menu: MDDropdownMenu = None
def build(self):
self.theme_cls.dynamic_color = True
return Builder.load_string(KV)
def get_instance_from_menu(self, name_item):
index = 0
rv = self.menu.ids.md_menu
opts = rv.layout_manager.view_opts
datas = rv.data[0]
for data in rv.data:
if data["text"] == name_item:
index = rv.data.index(data)
break
instance = rv.view_adapter.get_view(
index, datas, opts[index]["viewclass"]
)
return instance
def open_menu(self, menu_button):
menu_items = []
for item, method in {
"Set palette": lambda: self.set_palette(),
"Switch theme style": lambda: self.theme_switch(),
}.items():
menu_items.append({"text": item, "on_release": method})
self.menu = MDDropdownMenu(
caller=menu_button,
items=menu_items,
)
self.menu.open()
def set_palette(self):
instance_from_menu = self.get_instance_from_menu("Set palette")
available_palettes = [
name_color.capitalize() for name_color in hex_colormap.keys()
]
menu_items = []
for name_palette in available_palettes:
menu_items.append(
{
"text": name_palette,
"on_release": lambda x=name_palette: self.switch_palette(x),
}
)
MDDropdownMenu(
caller=instance_from_menu,
items=menu_items,
).open()
def switch_palette(self, selected_palette):
self.theme_cls.primary_palette = selected_palette
Clock.schedule_once(self.generate_cards, 0.5)
def theme_switch(self) -> None:
self.theme_cls.switch_theme()
Clock.schedule_once(self.generate_cards, 0.5)
def generate_cards(self, *args):
self.root.ids.card_list.data = []
for color in self.theme_cls.schemes_name_colors:
value = f"{color}Color"
self.root.ids.card_list.data.append(
{
"bg_color": getattr(self.theme_cls, value),
"text": value,
}
)
def on_start(self):
Clock.schedule_once(self.generate_cards)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color.gif
:align: center
Example of a dynamic color from an image
----------------------------------------
.. seealso::
:attr:`kivymd.theming.ThemeManager.path_to_wallpaper`
.. code-block:: python
import os
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.core.window.window_sdl2 import WindowSDL
from kivy.lang import Builder
from kivy.properties import StringProperty, ColorProperty
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.app import MDApp
KV = '''
<ColorCard>
orientation: "vertical"
MDLabel:
text: root.text
color: "grey"
adaptive_height: True
MDCard:
theme_bg_color: "Custom"
md_bg_color: root.bg_color
MDScreen:
md_bg_color: app.theme_cls.backgroundColor
MDRecycleView:
id: card_list
viewclass: "ColorCard"
bar_width: 0
RecycleGridLayout:
cols: 3
spacing: "16dp"
padding: "16dp"
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
'''
class ColorCard(MDBoxLayout):
text = StringProperty()
bg_color = ColorProperty()
class Example(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(on_dropfile=self.on_drop_file)
def on_drop_file(self, sdl: WindowSDL, path_to_file: str) -> None:
ext = os.path.splitext(path_to_file)[1]
if isinstance(path_to_file, bytes):
path_to_file = path_to_file.decode()
if isinstance(ext, bytes):
ext = ext.decode()
if ext in [".png", ".jpg"]:
self.theme_cls.path_to_wallpaper = path_to_file
Clock.schedule_once(self.generate_cards, 0.5)
def build(self):
self.theme_cls.dynamic_color = True
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
def theme_switch(self) -> None:
self.theme_cls.switch_theme()
Clock.schedule_once(self.generate_cards, 0.5)
def generate_cards(self, *args):
self.root.ids.card_list.data = []
for color in self.theme_cls.schemes_name_colors:
value = f"{color}Color"
self.root.ids.card_list.data.append(
{
"bg_color": getattr(self.theme_cls, value),
"text": value,
}
)
def on_start(self):
Clock.schedule_once(self.generate_cards)
Example().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/dynamic-color-path-to_wallpapper.gif
:align: center
"""
from kivy.properties import ColorProperty
class DynamicColor:
"""
Dynamic color class.
.. versionadded:: 2.0.0
"""
# Primary.
primaryColor = ColorProperty()
"""
Primary color.
:attr:`primaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
primaryContainerColor = ColorProperty()
"""
Primary container color.
:attr:`primaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Primary.
onPrimaryColor = ColorProperty()
"""
On primary color.
:attr:`onPrimaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onPrimaryContainerColor = ColorProperty()
"""
On primary container color.
:attr:`onPrimaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Secondary.
secondaryColor = ColorProperty()
"""
Secondary color.
:attr:`secondaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
secondaryContainerColor = ColorProperty()
"""
Secondary container color.
:attr:`secondaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Secondary.
onSecondaryColor = ColorProperty()
"""
On secondary color.
:attr:`onSecondaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onSecondaryContainerColor = ColorProperty()
"""
On secondary container color.
:attr:`onSecondaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Tertiary.
tertiaryColor = ColorProperty()
"""
Tertiary color.
:attr:`tertiaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
tertiaryContainerColor = ColorProperty()
"""
Tertiary container color.
:attr:`tertiaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Tertiary.
onTertiaryColor = ColorProperty()
"""
On tertiary color.
:attr:`onTertiaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onTertiaryContainerColor = ColorProperty()
"""
On tertiary container color.
:attr:`onTertiaryContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Surface.
surfaceColor = ColorProperty()
"""
Surface color.
:attr:`surfaceColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceDimColor = ColorProperty()
"""
Surface dim color.
:attr:`surfaceDimColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceBrightColor = ColorProperty()
"""
Surface bright color.
:attr:`surfaceBrightColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceContainerLowestColor = ColorProperty()
"""
Surface container lowest color.
:attr:`surfaceContainerLowestColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceContainerLowColor = ColorProperty()
"""
Surface container low color.
:attr:`surfaceContainerLowColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceContainerColor = ColorProperty()
"""
Surface container color.
:attr:`surfaceContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceContainerHighColor = ColorProperty()
"""
Surface container high color.
:attr:`surfaceContainerHighColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceContainerHighestColor = ColorProperty()
"""
Surface container highest color.
:attr:`surfaceContainerHighestColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceVariantColor = ColorProperty()
"""
Surface variant color.
:attr:`surfaceVariantColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
surfaceTintColor = ColorProperty()
"""
Surface tint color.
:attr:`surfaceTintColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Surface.
onSurfaceColor = ColorProperty()
"""
On surface color.
:attr:`onSurfaceColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onSurfaceLightColor = ColorProperty()
"""
On surface light color.
:attr:`onSurfaceLightColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onSurfaceVariantColor = ColorProperty()
"""
On surface variant color.
:attr:`onSurfaceVariantColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Inverse.
inverseSurfaceColor = ColorProperty()
"""
Inverse surface color.
:attr:`inverseSurfaceColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
inverseOnSurfaceColor = ColorProperty()
"""
Inverse on surface color.
:attr:`inverseOnSurfaceColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
inversePrimaryColor = ColorProperty()
"""
Inverse primary color.
:attr:`inversePrimaryColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Background.
backgroundColor = ColorProperty()
"""
Background color.
:attr:`backgroundColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Background.
onBackgroundColor = ColorProperty()
"""
On background color.
:attr:`onBackgroundColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Error.
errorColor = ColorProperty()
"""
Error color.
:attr:`errorColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
errorContainerColor = ColorProperty()
"""
Error container color.
:attr:`errorContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# On Error.
onErrorColor = ColorProperty()
"""
On error color.
:attr:`onErrorColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
onErrorContainerColor = ColorProperty()
"""
On error container color.
:attr:`onErrorContainerColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Outline.
outlineColor = ColorProperty()
"""
Outline color.
:attr:`outlineColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
outlineVariantColor = ColorProperty()
"""
Outline variant color.
:attr:`outlineVariantColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Shadow/scrim.
shadowColor = ColorProperty()
"""
Shadow color.
:attr:`shadowColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
scrimColor = ColorProperty()
"""
Scrim color.
:attr:`scrimColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Disabled.
disabledTextColor = ColorProperty()
"""
Disabled text color.
:attr:`disabledTextColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
# Transparent.
transparentColor = ColorProperty([0, 0, 0, 0])
"""
Transparent color.
:attr:`transparentColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `[0, 0, 0, 0]`.
"""
# Ripple.
rippleColor = ColorProperty("#BDBDBD")
"""
Ripple color.
:attr:`rippleColor` is an :class:`~kivy.properties.ColorProperty`
and defaults to `'#BDBDBD'`.
"""

View file

@ -1 +0,0 @@
from .fadingedge import FadingEdgeEffect

View file

@ -1,200 +0,0 @@
"""
Effects/FadingEdgeEffect
========================
.. versionadded:: 1.0.0
The `FadingEdgeEffect` class implements a fade effect for `KivyMD` widgets:
.. code-block:: python
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView
from kivymd.app import MDApp
from kivymd.effects.fadingedge.fadingedge import FadingEdgeEffect
from kivymd.uix.list import OneLineListItem
KV = '''
MDScreen:
FadeScrollView:
fade_height: self.height / 2
fade_color: root.md_bg_color
MDList:
id: container
'''
class FadeScrollView(FadingEdgeEffect, ScrollView):
pass
class Test(MDApp):
def build(self):
return Builder.load_string(KV)
def on_start(self):
for i in range(20):
self.root.ids.container.add_widget(
OneLineListItem(text=f"Single-line item {i}")
)
Test().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/fading-edge-effect-white.gif
:align: center
.. note:: Use the same color value for the fade_color parameter as for the
parent widget.
"""
from typing import Union
from kivy.clock import Clock
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Rectangle
from kivy.metrics import dp
from kivy.properties import BooleanProperty, ColorProperty, NumericProperty
from kivymd.theming import ThemableBehavior
__all_ = ("FadingEdgeEffect",)
class FadingEdgeEffect(ThemableBehavior):
"""
The class implements the fade effect.
.. versionadded:: 1.0.0
"""
fade_color = ColorProperty(None)
"""
Fade color.
:attr:`fade_color` is an :class:`~kivy.properties.ColorProperty`
and defaults to `None`.
"""
fade_height = NumericProperty(0)
"""
Fade height.
:attr:`fade_height` is an :class:`~kivy.properties.ColorProperty`
and defaults to `0`.
"""
edge_top = BooleanProperty(True)
"""
Display fade edge top.
:attr:`edge_top` is an :class:`~kivy.properties.BooleanProperty`
and defaults to `True`.
"""
edge_bottom = BooleanProperty(True)
"""
Display fade edge bottom.
:attr:`edge_bottom` is an :class:`~kivy.properties.BooleanProperty`
and defaults to `True`.
"""
_height_segment = 10
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self.set_fade)
# TODO: Perhaps it would be better if we used a Shader for the fade effect.
# But, I think the canvas instructions shouldn't affect performance
def set_fade(self, interval: Union[int, float]) -> None:
"""Draws a bottom and top fade border on the canvas."""
fade_color = (
self.theme_cls.primary_color
if not self.fade_color
else self.fade_color
)
height_segment = (
self.fade_height if self.fade_height else dp(100)
) // self._height_segment
alpha = 1.1
with self.canvas:
for i in range(self._height_segment):
alpha -= 0.1
Color(rgba=(fade_color[:-1] + [round(alpha, 1)]))
rectangle_top = (
Rectangle(
pos=(self.x, self.height - (i * height_segment)),
size=(self.width, height_segment),
)
if self.edge_top
else None
)
rectangle_bottom = (
Rectangle(
pos=(self.x, i * height_segment),
size=(self.width, height_segment),
)
if self.edge_bottom
else None
)
# How I hate lambda functions because of their length :(
# But I dont want to call the arguments by short,
# incomprehensible names 'a', 'b', 'c'.
self.bind(
pos=lambda instance_fadind_edge_effect, window_size, rectangle_top=rectangle_top, rectangle_bottom=rectangle_bottom, index=i: self.update_canvas(
instance_fadind_edge_effect,
window_size,
rectangle_top,
rectangle_bottom,
index,
),
size=lambda instance_fadind_edge_effect, window_size, rectangle_top=rectangle_top, rectangle_bottom=rectangle_bottom, index=i: self.update_canvas(
instance_fadind_edge_effect,
window_size,
rectangle_top,
rectangle_bottom,
index,
),
)
self.update_canvas(
self, self.size, rectangle_top, rectangle_bottom, i
)
def update_canvas(
self,
instance_fadind_edge_effect,
size: list[int, int],
rectangle_top: Rectangle,
rectangle_bottom: Rectangle,
index: int,
) -> None:
"""
Updates the position and size of the fade border on the canvas.
Called when the application screen is resized.
"""
height_segment = (
self.fade_height if self.fade_height else dp(100)
) // self._height_segment
if rectangle_top:
rectangle_top.pos = (
instance_fadind_edge_effect.x,
size[1]
- (index * height_segment - instance_fadind_edge_effect.y),
)
rectangle_top.size = (size[0], height_segment)
if rectangle_bottom:
rectangle_bottom.pos = (
instance_fadind_edge_effect.x,
index * height_segment + instance_fadind_edge_effect.y,
)
rectangle_bottom.size = (size[0], height_segment)

View file

@ -1 +0,0 @@
from .roulettescroll import RouletteScrollEffect

View file

@ -1,251 +0,0 @@
"""
Effects/RouletteScrollEffect
============================
This is a subclass of :class:`kivy.effects.ScrollEffect` that simulates the
motion of a roulette, or a notched wheel (think Wheel of Fortune). It is
primarily designed for emulating the effect of the iOS and android date pickers.
Usage
-----
Here's an example of using :class:`RouletteScrollEffect` for a
:class:`kivy.uix.scrollview.ScrollView`:
.. code-block:: python
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
# Preparing a `GridLayout` inside a `ScrollView`.
layout = GridLayout(cols=1, padding=10, size_hint=(None, None), width=500)
layout.bind(minimum_height=layout.setter('height'))
for i in range(30):
btn = Button(text=str(i), size=(480, 40), size_hint=(None, None))
layout.add_widget(btn)
root = ScrollView(
size_hint=(None, None),
size=(500, 320),
pos_hint={'center_x': .5, 'center_y': .5},
do_scroll_x=False,
)
root.add_widget(layout)
# Preparation complete. Now add the new scroll effect.
root.effect_y = RouletteScrollEffect(anchor=20, interval=40)
runTouchApp(root)
Here the :class:`ScrollView` scrolls through a series of buttons with height
40. We then attached a :class:`RouletteScrollEffect` with interval 40,
corresponding to the button heights. This allows the scrolling to stop at
the same offset no matter where it stops. The :attr:`RouletteScrollEffect.anchor`
adjusts this offset.
Customizations
--------------
Other settings that can be played with include:
:attr:`RouletteScrollEffect.pull_duration`,
:attr:`RouletteScrollEffect.coasting_alpha`,
:attr:`RouletteScrollEffect.pull_back_velocity`, and
:attr:`RouletteScrollEffect.terminal_velocity`.
See their module documentations for details.
:class:`RouletteScrollEffect` has one event ``on_coasted_to_stop`` that
is fired when the roulette stops, "making a selection". It can be listened to
for handling or cleaning up choice making.
"""
from math import ceil, exp, floor
from kivy.animation import Animation
from kivy.effects.scroll import ScrollEffect
from kivy.properties import AliasProperty, NumericProperty, ObjectProperty
__all_ = ("RouletteScrollEffect",)
class RouletteScrollEffect(ScrollEffect):
"""
This is a subclass of :class:`kivy.effects.ScrollEffect` that simulates the
motion of a roulette, or a notched wheel (think Wheel of Fortune). It is
primarily designed for emulating the effect of the iOS and android date pickers.
.. versionadded:: 0.104.2
"""
__events__ = ("on_coasted_to_stop",)
drag_threshold = NumericProperty(0)
"""
Overrides :attr:`ScrollEffect.drag_threshold` to abolish drag threshold.
.. note::
If using this with a :class:`Roulette` or other :class:`Tickline`
subclasses, what matters is :attr:`Tickline.drag_threshold`, which
is passed to this attribute in the end.
:attr:`drag_threshold` is an :class:`~kivy.properties.NumericProperty`
and defaults to `0`.
"""
min = NumericProperty(-float("inf"))
max = NumericProperty(float("inf"))
interval = NumericProperty(50)
"""
The interval of the values of the "roulette".
:attr:`interval` is an :class:`~kivy.properties.NumericProperty`
and defaults to `50`.
"""
anchor = NumericProperty(0)
"""
One of the valid stopping values.
:attr:`anchor` is an :class:`~kivy.properties.NumericProperty`
and defaults to `0`.
"""
pull_duration = NumericProperty(0.2)
"""
When movement slows around a stopping value, an animation is used
to pull it toward the nearest value. :attr:`pull_duration` is the duration
used for such an animation.
:attr:`pull_duration` is an :class:`~kivy.properties.NumericProperty`
and defaults to `0.2`.
"""
coasting_alpha = NumericProperty(0.5)
"""
When within :attr:`coasting_alpha` * :attr:`interval` of the
next notch and velocity is below :attr:`terminal_velocity`,
coasting begins and will end on the next notch.
:attr:`coasting_alpha` is an :class:`~kivy.properties.NumericProperty`
and defaults to `0.5`.
"""
pull_back_velocity = NumericProperty("50sp")
"""
The velocity below which the scroll value will be drawn to the
*nearest* notch instead of the *next* notch in the direction travelled.
:attr:`pull_back_velocity` is an :class:`~kivy.properties.NumericProperty`
and defaults to `50sp`.
"""
_anim = ObjectProperty(None)
def get_term_vel(self):
return (
exp(self.friction)
* self.interval
* self.coasting_alpha
/ self.pull_duration
)
def set_term_vel(self, val):
self.pull_duration = (
exp(self.friction) * self.interval * self.coasting_alpha / val
)
terminal_velocity = AliasProperty(
get_term_vel,
set_term_vel,
bind=["interval", "coasting_alpha", "pull_duration", "friction"],
cache=True,
)
"""
If velocity falls between :attr:`pull_back_velocity` and
:attr:`terminal velocity` then the movement will start to coast
to the next coming stopping value.
:attr:`terminal_velocity` is computed from a set formula given
:attr:`interval`, :attr:`coasting_alpha`, :attr:`pull_duration`,
and :attr:`friction`. Setting :attr:`terminal_velocity` has the
effect of setting :attr:`pull_duration`.
"""
def start(self, val, t=None):
if self._anim:
self._anim.stop(self)
return ScrollEffect.start(self, val, t=t)
def on_notch(self, *args):
return (self.scroll - self.anchor) % self.interval == 0
def nearest_notch(self, *args):
interval = float(self.interval)
anchor = self.anchor
n = round((self.scroll - anchor) / interval)
return anchor + n * interval
def next_notch(self, *args):
interval = float(self.interval)
anchor = self.anchor
round_ = ceil if self.velocity > 0 else floor
n = round_((self.scroll - anchor) / interval)
return anchor + n * interval
def near_notch(self, d=0.01):
nearest = self.nearest_notch()
if abs((nearest - self.scroll) / self.interval) % 1 < d:
return nearest
else:
return None
def near_next_notch(self, d=None):
d = d or self.coasting_alpha
next_ = self.next_notch()
if abs((next_ - self.scroll) / self.interval) % 1 < d:
return next_
else:
return None
def update_velocity(self, dt):
if self.is_manual:
return
velocity = self.velocity
t_velocity = self.terminal_velocity
next_ = self.near_next_notch()
pull_back_velocity = self.pull_back_velocity
if pull_back_velocity < abs(velocity) < t_velocity and next_:
duration = abs((next_ - self.scroll) / self.velocity)
anim = Animation(
scroll=next_,
duration=duration,
)
self._anim = anim
anim.on_complete = self._coasted_to_stop
anim.start(self)
return
if abs(velocity) < pull_back_velocity and not self.on_notch():
anim = Animation(
scroll=self.nearest_notch(),
duration=self.pull_duration,
t="in_out_circ",
)
self._anim = anim
anim.on_complete = self._coasted_to_stop
anim.start(self)
else:
self.velocity -= self.velocity * self.friction
self.apply_distance(self.velocity * dt)
self.trigger_velocity_update()
def on_coasted_to_stop(self, *args):
"""
This event fires when the roulette has stopped, `making a selection`.
"""
def _coasted_to_stop(self, *args):
self.velocity = 0
self.dispatch("on_coasted_to_stop")

View file

@ -7,11 +7,11 @@ from kivy.factory import Factory
register = Factory.register
register("MDSegmentedButton", module="kivymd.uix.segmentedbutton")
register("MDSegmentedButtonItem", module="kivymd.uix.segmentedbutton")
register("MDSegmentButtonIcon", module="kivymd.uix.segmentedbutton")
register("MDSegmentButtonLabel", module="kivymd.uix.segmentedbutton")
register("MDScrollView", module="kivymd.uix.scrollview")
register("MDRecycleView", module="kivymd.uix.recycleview")
register("MDResponsiveLayout", module="kivymd.uix.responsivelayout")
register("MDSegmentedControl", module="kivymd.uix.segmentedcontrol")
register("MDSegmentedControlItem", module="kivymd.uix.segmentedcontrol")
register("MDSliverAppbar", module="kivymd.uix.sliverappbar")
register("MDSliverAppbarContent", module="kivymd.uix.sliverappbar")
register("MDSliverAppbarHeader", module="kivymd.uix.sliverappbar")
@ -19,8 +19,9 @@ register("MDNavigationRailItem", module="kivymd.uix.navigationrail")
register("MDNavigationRail", module="kivymd.uix.navigationrail")
register("MDNavigationRailFabButton", module="kivymd.uix.navigationrail")
register("MDNavigationRailMenuButton", module="kivymd.uix.navigationrail")
register("MDNavigationRailItemIcon", module="kivymd.uix.navigationrail")
register("MDNavigationRailItemLabel", module="kivymd.uix.navigationrail")
register("MDSwiper", module="kivymd.uix.swiper")
register("MDCarousel", module="kivymd.uix.carousel")
register("MDWidget", module="kivymd.uix.widget")
register("MDFloatLayout", module="kivymd.uix.floatlayout")
register("MDAnchorLayout", module="kivymd.uix.anchorlayout")
@ -32,80 +33,102 @@ register("MDRelativeLayout", module="kivymd.uix.relativelayout")
register("MDGridLayout", module="kivymd.uix.gridlayout")
register("MDStackLayout", module="kivymd.uix.stacklayout")
register("MDExpansionPanel", module="kivymd.uix.expansionpanel")
register("MDExpansionPanelOneLine", module="kivymd.uix.expansionpanel")
register("MDExpansionPanelTwoLine", module="kivymd.uix.expansionpanel")
register("MDExpansionPanelThreeLine", module="kivymd.uix.expansionpanel")
register("MDExpansionPanelHeader", module="kivymd.uix.expansionpanel")
register("MDExpansionPanelContent", module="kivymd.uix.expansionpanel")
register("FitImage", module="kivymd.uix.fitimage")
register("MDBackdrop", module="kivymd.uix.backdrop")
register("MDBanner", module="kivymd.uix.banner")
register("MDTooltip", module="kivymd.uix.tooltip")
register("MDTooltipPlain", module="kivymd.uix.tooltip")
register("MDTooltipRich", module="kivymd.uix.tooltip")
register("MDTooltipRichActionButton", module="kivymd.uix.tooltip")
register("MDTooltipRichSubhead", module="kivymd.uix.tooltip")
register("MDTooltipRichSupportingText", module="kivymd.uix.tooltip")
register("MDBottomSheet", module="kivymd.uix.bottomsheet")
register("MDBottomNavigation", module="kivymd.uix.bottomnavigation")
register("MDBottomNavigationItem", module="kivymd.uix.bottomnavigation")
register("MDBottomSheetDragHandle", module="kivymd.uix.bottomsheet")
register("MDBottomSheetDragHandleButton", module="kivymd.uix.bottomsheet")
register("MDBottomSheetDragHandleTitle", module="kivymd.uix.bottomsheet")
register("MDNavigationBar", module="kivymd.uix.navigationbar")
register("MDNavigationItem", module="kivymd.uix.navigationbar")
register("MDNavigationItemLabel", module="kivymd.uix.navigationbar")
register("MDNavigationItemIcon", module="kivymd.uix.navigationbar")
register("MDToggleButton", module="kivymd.uix.behaviors.toggle_behavior")
register("MDFloatingActionButtonSpeedDial", module="kivymd.uix.button")
register("MDButton", module="kivymd.uix.button")
register("MDButtonText", module="kivymd.uix.button")
register("MDButtonIcon", module="kivymd.uix.button")
register("MDFabButton", module="kivymd.uix.button")
register("MDIconButton", module="kivymd.uix.button")
register("MDRoundImageButton", module="kivymd.uix.button")
register("MDFlatButton", module="kivymd.uix.button")
register("MDRaisedButton", module="kivymd.uix.button")
register("MDFloatingActionButton", module="kivymd.uix.button")
register("MDRectangleFlatButton", module="kivymd.uix.button")
register("MDTextButton", module="kivymd.uix.button")
register("MDCustomRoundIconButton", module="kivymd.uix.button")
register("MDRoundFlatButton", module="kivymd.uix.button")
register("MDFillRoundFlatButton", module="kivymd.uix.button")
register("MDRectangleFlatIconButton", module="kivymd.uix.button")
register("MDRoundFlatIconButton", module="kivymd.uix.button")
register("MDFillRoundFlatIconButton", module="kivymd.uix.button")
register("MDExtendedFabButton", module="kivymd.uix.button")
register("MDExtendedFabButtonIcon", module="kivymd.uix.button")
register("MDExtendedFabButtonText", module="kivymd.uix.button")
register("MDCard", module="kivymd.uix.card")
register("MDSeparator", module="kivymd.uix.card")
register("MDSelectionList", module="kivymd.uix.selection")
register("MDDivider", module="kivymd.uix.divider")
register("MDChip", module="kivymd.uix.chip")
register("MDChipLeadingAvatar", module="kivymd.uix.chip")
register("MDChipLeadingIcon", module="kivymd.uix.chip")
register("MDChipTrailingIcon", module="kivymd.uix.chip")
register("MDChipText", module="kivymd.uix.chip")
register("MDSmartTile", module="kivymd.uix.imagelist")
register("MDSmartTileOverlayContainer", module="kivymd.uix.imagelist")
register("MDSmartTileImage", module="kivymd.uix.imagelist")
register("MDLabel", module="kivymd.uix.label")
register("MDIcon", module="kivymd.uix.label")
register("MDBadge", module="kivymd.uix.badge")
register("MDList", module="kivymd.uix.list")
register("ILeftBody", module="kivymd.uix.list")
register("ILeftBodyTouch", module="kivymd.uix.list")
register("IRightBody", module="kivymd.uix.list")
register("IRightBodyTouch", module="kivymd.uix.list")
register("OneLineListItem", module="kivymd.uix.list")
register("TwoLineListItem", module="kivymd.uix.list")
register("ThreeLineListItem", module="kivymd.uix.list")
register("OneLineAvatarListItem", module="kivymd.uix.list")
register("TwoLineAvatarListItem", module="kivymd.uix.list")
register("ThreeLineAvatarListItem", module="kivymd.uix.list")
register("OneLineIconListItem", module="kivymd.uix.list")
register("TwoLineIconListItem", module="kivymd.uix.list")
register("ThreeLineIconListItem", module="kivymd.uix.list")
register("OneLineRightIconListItem", module="kivymd.uix.list")
register("TwoLineRightIconListItem", module="kivymd.uix.list")
register("ThreeLineRightIconListItem", module="kivymd.uix.list")
register("OneLineAvatarIconListItem", module="kivymd.uix.list")
register("TwoLineAvatarIconListItem", module="kivymd.uix.list")
register("ThreeLineAvatarIconListItem", module="kivymd.uix.list")
register("MDListItem", module="kivymd.uix.list")
register("MDListItemHeadlineText", module="kivymd.uix.list")
register("MDListItemSupportingText", module="kivymd.uix.list")
register("MDListItemTrailingSupportingText", module="kivymd.uix.list")
register("MDListItemLeadingIcon", module="kivymd.uix.list")
register("MDListItemTrailingIcon", module="kivymd.uix.list")
register("MDListItemTrailingCheckbox", module="kivymd.uix.list")
register("MDListItemTertiaryText", module="kivymd.uix.list")
register("HoverBehavior", module="kivymd.uix.behaviors.hover_behavior")
register("FocusBehavior", module="kivymd.uix.behaviors.focus_behavior")
register("MagicBehavior", module="kivymd.uix.behaviors.magic_behavior")
register("MDNavigationDrawer", module="kivymd.uix.navigationdrawer")
register("MDNavigationLayout", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerMenu", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerHeader", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerItem", module="kivymd.uix.navigationdrawer")
register(
"MDNavigationDrawerItemLeadingIcon", module="kivymd.uix.navigationdrawer"
)
register(
"MDNavigationDrawerItemTrailingText", module="kivymd.uix.navigationdrawer"
)
register("MDNavigationDrawerHeader", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerItemText", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerLabel", module="kivymd.uix.navigationdrawer")
register("MDNavigationDrawerDivider", module="kivymd.uix.navigationdrawer")
register("MDProgressBar", module="kivymd.uix.progressbar")
register("MDScrollViewRefreshLayout", module="kivymd.uix.refreshlayout")
register("MDCheckbox", module="kivymd.uix.selectioncontrol")
register("MDSwitch", module="kivymd.uix.selectioncontrol")
register("MDSlider", module="kivymd.uix.slider")
register("MDSpinner", module="kivymd.uix.spinner")
register("MDTabs", module="kivymd.uix.tab")
register("MDCircularProgressIndicator", module="kivymd.uix.progressindicator")
register("MDLinearProgressIndicator", module="kivymd.uix.progressindicator")
register("MDTabsPrimary", module="kivymd.uix.tab")
register("MDTabsSecondary", module="kivymd.uix.tab")
register("MDTabsItem", module="kivymd.uix.tab")
register("MDTabsItemSecondary", module="kivymd.uix.tab")
register("MDTabsBadge", module="kivymd.uix.tab")
register("MDTabsItemIcon", module="kivymd.uix.tab")
register("MDTabsItemText", module="kivymd.uix.tab")
register("MDTabsCarousel", module="kivymd.uix.tab")
register("MDTextField", module="kivymd.uix.textfield")
register("MDTextFieldRect", module="kivymd.uix.textfield")
register("MDTopAppBar", module="kivymd.uix.toolbar")
register("MDBottomAppBar", module="kivymd.uix.toolbar")
register("MDTextFieldHelperText", module="kivymd.uix.textfield")
register("MDTextFieldMaxLengthText", module="kivymd.uix.textfield")
register("MDTextFieldHintText", module="kivymd.uix.textfield")
register("MDTextFieldLeadingIcon", module="kivymd.uix.textfield")
register("MDTextFieldTrailingIcon", module="kivymd.uix.textfield")
register("MDTopAppBarTrailingButtonContainer", module="kivymd.uix.appbar")
register("MDTopAppBarLeadingButtonContainer", module="kivymd.uix.appbar")
register("MDFabBottomAppBarButton", module="kivymd.uix.appbar")
register("MDActionBottomAppBarButton", module="kivymd.uix.appbar")
register("MDTopAppBarTitle", module="kivymd.uix.appbar")
register("MDTopAppBar", module="kivymd.uix.appbar")
register("MDBottomAppBar", module="kivymd.uix.appbar")
register("MDActionTopAppBarButton", module="kivymd.uix.appbar")
register("MDDropDownItem", module="kivymd.uix.dropdownitem")
register("MDDropDownItemText", module="kivymd.uix.dropdownitem")
register("MDCircularLayout", module="kivymd.uix.circularlayout")
register("MDHeroFrom", module="kivymd.uix.hero")
register("MDHeroTo", module="kivymd.uix.hero")

View file

@ -1,5 +1,5 @@
"""
Themes/Font Definitions
Themes/Font definitions
=======================
.. seealso::
@ -8,6 +8,7 @@ Themes/Font Definitions
"""
from kivy.core.text import LabelBase
from kivy.metrics import sp
from kivymd import fonts_path
@ -48,22 +49,102 @@ fonts = [
for font in fonts:
LabelBase.register(**font)
theme_font_styles = [
"H1",
"H2",
"H3",
"H4",
"H5",
"H6",
"Subtitle1",
"Subtitle2",
"Body1",
"Body2",
"Button",
"Caption",
"Overline",
"Icon",
]
# TODO: Add `weight` properties.
theme_font_styles = {
"Icon": {
"large": {
"line-height": 1,
"font-name": "Icons",
"font-size": sp(24),
},
},
"Display": {
"large": {
"line-height": 1.64,
"font-name": "Roboto",
"font-size": sp(57),
},
"medium": {
"line-height": 1.52,
"font-name": "Roboto",
"font-size": sp(45),
},
"small": {
"line-height": 1.44,
"font-name": "Roboto",
"font-size": sp(36),
},
},
"Headline": {
"large": {
"line-height": 1.40,
"font-name": "Roboto",
"font-size": sp(32),
},
"medium": {
"line-height": 1.36,
"font-name": "Roboto",
"font-size": sp(28),
},
"small": {
"line-height": 1.32,
"font-name": "Roboto",
"font-size": sp(24),
},
},
"Title": {
"large": {
"line-height": 1.28,
"font-name": "Roboto",
"font-size": sp(22),
},
"medium": {
"line-height": 1.24,
"font-name": "Roboto",
"font-size": sp(16),
},
"small": {
"line-height": 1.20,
"font-name": "Roboto",
"font-size": sp(14),
},
},
"Body": {
"large": {
"line-height": 1.24,
"font-name": "Roboto",
"font-size": sp(16),
},
"medium": {
"line-height": 1.20,
"font-name": "Roboto",
"font-size": sp(14),
},
"small": {
"line-height": 1.16,
"font-name": "Roboto",
"font-size": sp(12),
},
},
"Label": {
"large": {
"line-height": 1.20,
"font-name": "Roboto",
"font-size": sp(14),
},
"medium": {
"line-height": 1.16,
"font-name": "Roboto",
"font-size": sp(12),
},
"small": {
"line-height": 1.16,
"font-name": "Roboto",
"font-size": sp(11),
},
},
}
"""
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-styles-2.png
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/label-font-style-preview.png
:align: center
"""

View file

@ -2,17 +2,17 @@
Themes/Icon Definitions
=======================
.. seealso::
.. seealso::Updateeeee
`Material Design Icons <https://materialdesignicons.com/>`_
`Material Design Icons <https://m3.material.io/styles/icons/overview>`_
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/material-icons.png
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/material-m3-icons.png
:align: center
List of icons from materialdesignicons.com. These expanded material design
icons are maintained by Austin Andrews (Templarian on Github).
LAST UPDATED: Version 7.2.96
Version 7.4.47
To preview the icons and their names, you can use the following application:
----------------------------------------------------------------------------
@ -21,25 +21,28 @@ To preview the icons and their names, you can use the following application:
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.screenmanager import Screen
from kivymd.icon_definitions import md_icons
from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
from kivymd.uix.list import OneLineIconListItem
from kivymd.uix.list import MDListItem
Builder.load_string(
'''
#:import images_path kivymd.images_path
<CustomOneLineIconListItem>
<IconItem>
IconLeftWidget:
MDListItemLeadingIcon:
icon: root.icon
MDListItemSupportingText:
text: root.text
<PreviousMDIcons>
md_bg_color: self.theme_cls.backgroundColor
MDBoxLayout:
orientation: 'vertical'
@ -51,6 +54,7 @@ To preview the icons and their names, you can use the following application:
MDIconButton:
icon: 'magnify'
pos_hint: {'center_y': .5}
MDTextField:
id: search_field
@ -63,7 +67,7 @@ To preview the icons and their names, you can use the following application:
key_size: 'height'
RecycleBoxLayout:
padding: dp(10)
padding: dp(10), dp(10), 0, dp(10)
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
@ -73,19 +77,19 @@ To preview the icons and their names, you can use the following application:
)
class CustomOneLineIconListItem(OneLineIconListItem):
class IconItem(MDListItem):
icon = StringProperty()
text = StringProperty()
class PreviousMDIcons(Screen):
class PreviousMDIcons(MDScreen):
def set_list_md_icons(self, text="", search=False):
'''Builds a list of icons for the screen MDIcons.'''
def add_icon_item(name_icon):
self.ids.rv.data.append(
{
"viewclass": "CustomOneLineIconListItem",
"viewclass": "IconItem",
"icon": name_icon,
"text": name_icon,
"callback": lambda x: x,
@ -115,7 +119,7 @@ To preview the icons and their names, you can use the following application:
MainApp().run()
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/md-icons-previous.gif
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/m3-icons-previous.gif
:align: center
"""
@ -149,9 +153,12 @@ md_icons = {
"account-badge": "\U000F1B0A",
"account-badge-outline": "\U000F1B0B",
"account-box": "\U000F0006",
"account-box-edit-outline": "\U000F1CC8",
"account-box-minus-outline": "\U000F1CC9",
"account-box-multiple": "\U000F0934",
"account-box-multiple-outline": "\U000F100A",
"account-box-outline": "\U000F0007",
"account-box-plus-outline": "\U000F1CCA",
"account-cancel": "\U000F12DF",
"account-cancel-outline": "\U000F12E0",
"account-card": "\U000F1BA4",
@ -181,6 +188,10 @@ md_icons = {
"account-edit-outline": "\U000F0FFB",
"account-eye": "\U000F0420",
"account-eye-outline": "\U000F127B",
"account-file": "\U000F1CA7",
"account-file-outline": "\U000F1CA8",
"account-file-text": "\U000F1CA9",
"account-file-text-outline": "\U000F1CAA",
"account-filter": "\U000F0936",
"account-filter-outline": "\U000F0F9D",
"account-group": "\U000F0849",
@ -669,6 +680,8 @@ md_icons = {
"arrow-left-thin-circle-outline": "\U000F159A",
"arrow-left-top": "\U000F17A7",
"arrow-left-top-bold": "\U000F17A8",
"arrow-oscillating": "\U000F1C91",
"arrow-oscillating-off": "\U000F1C92",
"arrow-projectile": "\U000F1840",
"arrow-projectile-multiple": "\U000F183F",
"arrow-right": "\U000F0054",
@ -840,6 +853,8 @@ md_icons = {
"bag-personal-off": "\U000F0E11",
"bag-personal-off-outline": "\U000F0E12",
"bag-personal-outline": "\U000F0E13",
"bag-personal-plus": "\U000F1CA4",
"bag-personal-plus-outline": "\U000F1CA5",
"bag-personal-tag": "\U000F1B0C",
"bag-personal-tag-outline": "\U000F1B0D",
"bag-suitcase": "\U000F158B",
@ -1145,10 +1160,12 @@ md_icons = {
"book-off-outline": "\U000F1695",
"book-open": "\U000F00BD",
"book-open-blank-variant": "\U000F00BE",
"book-open-blank-variant-outline": "\U000F1CCB",
"book-open-outline": "\U000F0B63",
"book-open-page-variant": "\U000F05DA",
"book-open-page-variant-outline": "\U000F15D6",
"book-open-variant": "\U000F14F7",
"book-open-variant-outline": "\U000F1CCC",
"book-outline": "\U000F0B64",
"book-play": "\U000F0E82",
"book-play-outline": "\U000F0E83",
@ -1339,9 +1356,11 @@ md_icons = {
"bus-multiple": "\U000F0F3F",
"bus-school": "\U000F079F",
"bus-side": "\U000F07A0",
"bus-sign": "\U000F1CC1",
"bus-stop": "\U000F1012",
"bus-stop-covered": "\U000F1013",
"bus-stop-uncovered": "\U000F1014",
"bus-wrench": "\U000F1CC2",
"butterfly": "\U000F1589",
"butterfly-outline": "\U000F158A",
"button-cursor": "\U000F1B4F",
@ -1521,6 +1540,7 @@ md_icons = {
"car-defrost-rear": "\U000F0D62",
"car-door": "\U000F0B6B",
"car-door-lock": "\U000F109D",
"car-door-lock-open": "\U000F1C81",
"car-electric": "\U000F0B6C",
"car-electric-outline": "\U000F15B5",
"car-emergency": "\U000F160F",
@ -1639,6 +1659,7 @@ md_icons = {
"cash-100": "\U000F0115",
"cash-check": "\U000F14EE",
"cash-clock": "\U000F1A91",
"cash-edit": "\U000F1CAB",
"cash-fast": "\U000F185C",
"cash-lock": "\U000F14EA",
"cash-lock-open": "\U000F14EB",
@ -1702,6 +1723,7 @@ md_icons = {
"chair-school": "\U000F0125",
"chandelier": "\U000F1793",
"charity": "\U000F0C4F",
"charity-search": "\U000F1C82",
"chart-arc": "\U000F0126",
"chart-areaspline": "\U000F0127",
"chart-areaspline-variant": "\U000F0E91",
@ -1710,6 +1732,8 @@ md_icons = {
"chart-bell-curve": "\U000F0C50",
"chart-bell-curve-cumulative": "\U000F0FA7",
"chart-box": "\U000F154D",
"chart-box-multiple": "\U000F1CCD",
"chart-box-multiple-outline": "\U000F1CCE",
"chart-box-outline": "\U000F154E",
"chart-box-plus-outline": "\U000F154F",
"chart-bubble": "\U000F05E3",
@ -2026,6 +2050,8 @@ md_icons = {
"cloud-cog-outline": "\U000F1BF1",
"cloud-download": "\U000F0162",
"cloud-download-outline": "\U000F0B7D",
"cloud-key": "\U000F1CA1",
"cloud-key-outline": "\U000F1CA2",
"cloud-lock": "\U000F11F1",
"cloud-lock-open": "\U000F1BF2",
"cloud-lock-open-outline": "\U000F1BF3",
@ -2063,6 +2089,10 @@ md_icons = {
"coach-lamp-variant": "\U000F1A37",
"coat-rack": "\U000F109E",
"code-array": "\U000F0168",
"code-block-braces": "\U000F1C83",
"code-block-brackets": "\U000F1C84",
"code-block-parentheses": "\U000F1C85",
"code-block-tags": "\U000F1C86",
"code-braces": "\U000F0169",
"code-braces-box": "\U000F10D6",
"code-brackets": "\U000F016A",
@ -2501,6 +2531,7 @@ md_icons = {
"diamond": "\U000F0B8A",
"diamond-outline": "\U000F0B8B",
"diamond-stone": "\U000F01C8",
"diaper-outline": "\U000F1CCF",
"dice-1": "\U000F01CA",
"dice-1-outline": "\U000F114A",
"dice-2": "\U000F01CB",
@ -2584,6 +2615,7 @@ md_icons = {
"donkey": "\U000F07C2",
"door": "\U000F081A",
"door-closed": "\U000F081B",
"door-closed-cancel": "\U000F1C93",
"door-closed-lock": "\U000F10AF",
"door-open": "\U000F081C",
"door-sliding": "\U000F181E",
@ -2611,6 +2643,7 @@ md_icons = {
"download-lock": "\U000F1320",
"download-lock-outline": "\U000F1321",
"download-multiple": "\U000F09E9",
"download-multiple-outline": "\U000F1CD0",
"download-network": "\U000F06F4",
"download-network-outline": "\U000F0C66",
"download-off": "\U000F10B0",
@ -2643,7 +2676,10 @@ md_icons = {
"earbuds-off-outline": "\U000F1851",
"earbuds-outline": "\U000F1852",
"earth": "\U000F01E7",
"earth-arrow-down": "\U000F1C87",
"earth-arrow-left": "\U000F1C88",
"earth-arrow-right": "\U000F1311",
"earth-arrow-up": "\U000F1C89",
"earth-box": "\U000F06CD",
"earth-box-minus": "\U000F1407",
"earth-box-off": "\U000F06CE",
@ -2747,11 +2783,17 @@ md_icons = {
"emoticon-kiss-outline": "\U000F0C73",
"emoticon-lol": "\U000F1214",
"emoticon-lol-outline": "\U000F1215",
"emoticon-minus": "\U000F1CB2",
"emoticon-minus-outline": "\U000F1CB3",
"emoticon-neutral": "\U000F0C74",
"emoticon-neutral-outline": "\U000F01F6",
"emoticon-outline": "\U000F01F2",
"emoticon-plus": "\U000F1CB4",
"emoticon-plus-outline": "\U000F1CB5",
"emoticon-poop": "\U000F01F7",
"emoticon-poop-outline": "\U000F0C75",
"emoticon-remove": "\U000F1CB6",
"emoticon-remove-outline": "\U000F1CB7",
"emoticon-sad": "\U000F0C76",
"emoticon-sad-outline": "\U000F01F8",
"emoticon-sick": "\U000F157C",
@ -2781,6 +2823,7 @@ md_icons = {
"ethernet": "\U000F0200",
"ethernet-cable": "\U000F0201",
"ethernet-cable-off": "\U000F0202",
"ethernet-off": "\U000F1CD1",
"ev-plug-ccs1": "\U000F1519",
"ev-plug-ccs2": "\U000F151A",
"ev-plug-chademo": "\U000F151B",
@ -2811,6 +2854,7 @@ md_icons = {
"eye-check-outline": "\U000F0D05",
"eye-circle": "\U000F0B94",
"eye-circle-outline": "\U000F0B95",
"eye-closed": "\U000F1CA3",
"eye-lock": "\U000F1C06",
"eye-lock-open": "\U000F1C07",
"eye-lock-open-outline": "\U000F1C08",
@ -3090,6 +3134,7 @@ md_icons = {
"fire-hydrant-alert": "\U000F1138",
"fire-hydrant-off": "\U000F1139",
"fire-off": "\U000F1722",
"fire-station": "\U000F1CC3",
"fire-truck": "\U000F08AB",
"firebase": "\U000F0967",
"firefox": "\U000F0239",
@ -3531,6 +3576,8 @@ md_icons = {
"gas-burner": "\U000F1A1B",
"gas-cylinder": "\U000F0647",
"gas-station": "\U000F0298",
"gas-station-in-use": "\U000F1CC4",
"gas-station-in-use-outline": "\U000F1CC5",
"gas-station-off": "\U000F1409",
"gas-station-off-outline": "\U000F140A",
"gas-station-outline": "\U000F0EB8",
@ -3559,6 +3606,9 @@ md_icons = {
"gender-male-female-variant": "\U000F113F",
"gender-non-binary": "\U000F1140",
"gender-transgender": "\U000F029F",
"generator-mobile": "\U000F1C8A",
"generator-portable": "\U000F1C8B",
"generator-stationary": "\U000F1C8C",
"gentoo": "\U000F08E8",
"gesture": "\U000F07CB",
"gesture-double-tap": "\U000F073C",
@ -3794,6 +3844,7 @@ md_icons = {
"heart-pulse": "\U000F05F6",
"heart-remove": "\U000F1430",
"heart-remove-outline": "\U000F1433",
"heart-search": "\U000F1C8D",
"heart-settings": "\U000F1665",
"heart-settings-outline": "\U000F1666",
"heat-pump": "\U000F1A43",
@ -3918,7 +3969,10 @@ md_icons = {
"hospital-building": "\U000F02E1",
"hospital-marker": "\U000F02E2",
"hot-tub": "\U000F0828",
"hours-12": "\U000F1C94",
"hours-24": "\U000F1478",
"hub": "\U000F1C95",
"hub-outline": "\U000F1C96",
"hubspot": "\U000F0D17",
"hulu": "\U000F0829",
"human": "\U000F02E6",
@ -3933,6 +3987,7 @@ md_icons = {
"human-female-boy": "\U000F0A59",
"human-female-dance": "\U000F15C9",
"human-female-female": "\U000F0A5A",
"human-female-female-child": "\U000F1C8E",
"human-female-girl": "\U000F0A5B",
"human-greeting": "\U000F17C4",
"human-greeting-proximity": "\U000F159D",
@ -3950,6 +4005,7 @@ md_icons = {
"human-male-height": "\U000F0EFB",
"human-male-height-variant": "\U000F0EFC",
"human-male-male": "\U000F0A5E",
"human-male-male-child": "\U000F1C8F",
"human-non-binary": "\U000F1848",
"human-pregnant": "\U000F05CF",
"human-queue": "\U000F1571",
@ -4063,6 +4119,59 @@ md_icons = {
"integrated-circuit-chip": "\U000F1913",
"invert-colors": "\U000F0301",
"invert-colors-off": "\U000F0E4A",
"invoice": "\U000F1CD2",
"invoice-arrow-left": "\U000F1CD3",
"invoice-arrow-left-outline": "\U000F1CD4",
"invoice-arrow-right": "\U000F1CD5",
"invoice-arrow-right-outline": "\U000F1CD6",
"invoice-check": "\U000F1CD7",
"invoice-check-outline": "\U000F1CD8",
"invoice-clock": "\U000F1CD9",
"invoice-clock-outline": "\U000F1CDA",
"invoice-edit": "\U000F1CDB",
"invoice-edit-outline": "\U000F1CDC",
"invoice-export-outline": "\U000F1CDD",
"invoice-fast": "\U000F1CDE",
"invoice-fast-outline": "\U000F1CDF",
"invoice-import": "\U000F1CE0",
"invoice-import-outline": "\U000F1CE1",
"invoice-list": "\U000F1CE2",
"invoice-list-outline": "\U000F1CE3",
"invoice-minus": "\U000F1CE4",
"invoice-minus-outline": "\U000F1CE5",
"invoice-multiple": "\U000F1CE6",
"invoice-multiple-outline": "\U000F1CE7",
"invoice-outline": "\U000F1CE8",
"invoice-plus": "\U000F1CE9",
"invoice-plus-outline": "\U000F1CEA",
"invoice-remove": "\U000F1CEB",
"invoice-remove-outline": "\U000F1CEC",
"invoice-send": "\U000F1CED",
"invoice-send-outline": "\U000F1CEE",
"invoice-text": "\U000F1CEF",
"invoice-text-arrow-left": "\U000F1CF0",
"invoice-text-arrow-left-outline": "\U000F1CF1",
"invoice-text-arrow-right": "\U000F1CF2",
"invoice-text-arrow-right-outline": "\U000F1CF3",
"invoice-text-check": "\U000F1CF4",
"invoice-text-check-outline": "\U000F1CF5",
"invoice-text-clock": "\U000F1CF6",
"invoice-text-clock-outline": "\U000F1CF7",
"invoice-text-edit": "\U000F1CF8",
"invoice-text-edit-outline": "\U000F1CF9",
"invoice-text-fast": "\U000F1CFA",
"invoice-text-fast-outline": "\U000F1CFB",
"invoice-text-minus": "\U000F1CFC",
"invoice-text-minus-outline": "\U000F1CFD",
"invoice-text-multiple": "\U000F1CFE",
"invoice-text-multiple-outline": "\U000F1CFF",
"invoice-text-outline": "\U000F1D00",
"invoice-text-plus": "\U000F1D01",
"invoice-text-plus-outline": "\U000F1D02",
"invoice-text-remove": "\U000F1D03",
"invoice-text-remove-outline": "\U000F1D04",
"invoice-text-send": "\U000F1D05",
"invoice-text-send-outline": "\U000F1D06",
"iobroker": "\U000F12E8",
"ip": "\U000F0A5F",
"ip-network": "\U000F0A60",
@ -4073,6 +4182,7 @@ md_icons = {
"iron-board": "\U000F1838",
"iron-outline": "\U000F1825",
"island": "\U000F104F",
"island-variant": "\U000F1CC6",
"iv-bag": "\U000F10B9",
"jabber": "\U000F0DD5",
"jeepney": "\U000F0302",
@ -4313,6 +4423,9 @@ md_icons = {
"link-box-outline": "\U000F0D1B",
"link-box-variant": "\U000F0D1C",
"link-box-variant-outline": "\U000F0D1D",
"link-circle": "\U000F1CAC",
"link-circle-outline": "\U000F1CAD",
"link-edit": "\U000F1CAE",
"link-lock": "\U000F10BA",
"link-off": "\U000F0338",
"link-plus": "\U000F0C94",
@ -4487,9 +4600,11 @@ md_icons = {
"medication-outline": "\U000F1B15",
"meditation": "\U000F117B",
"memory": "\U000F035B",
"memory-arrow-down": "\U000F1CA6",
"menorah": "\U000F17D4",
"menorah-fire": "\U000F17D5",
"menu": "\U000F035C",
"menu-close": "\U000F1C90",
"menu-down": "\U000F035D",
"menu-down-outline": "\U000F06B6",
"menu-left": "\U000F035E",
@ -4694,10 +4809,16 @@ md_icons = {
"motorbike-off": "\U000F1B16",
"mouse": "\U000F037D",
"mouse-bluetooth": "\U000F098B",
"mouse-left-click": "\U000F1D07",
"mouse-left-click-outline": "\U000F1D08",
"mouse-move-down": "\U000F1550",
"mouse-move-up": "\U000F1551",
"mouse-move-vertical": "\U000F1552",
"mouse-off": "\U000F037E",
"mouse-outline": "\U000F1D09",
"mouse-right-click": "\U000F1D0A",
"mouse-right-click-outline": "\U000F1D0B",
"mouse-scroll-wheel": "\U000F1D0C",
"mouse-variant": "\U000F037F",
"mouse-variant-off": "\U000F0380",
"move-resize": "\U000F0655",
@ -5139,7 +5260,13 @@ md_icons = {
"parking": "\U000F03E3",
"party-popper": "\U000F1056",
"passport": "\U000F07E3",
"passport-alert": "\U000F1CB8",
"passport-biometric": "\U000F0DE1",
"passport-cancel": "\U000F1CB9",
"passport-check": "\U000F1CBA",
"passport-minus": "\U000F1CBB",
"passport-plus": "\U000F1CBC",
"passport-remove": "\U000F1CBD",
"pasta": "\U000F1160",
"patio-heater": "\U000F0F80",
"patreon": "\U000F0882",
@ -5349,6 +5476,7 @@ md_icons = {
"plus-network-outline": "\U000F0CBA",
"plus-outline": "\U000F0705",
"plus-thick": "\U000F11EC",
"pocket": "\U000F1CBE",
"podcast": "\U000F0994",
"podium": "\U000F0D25",
"podium-bronze": "\U000F0D26",
@ -5478,6 +5606,7 @@ md_icons = {
"progress-question": "\U000F1522",
"progress-star": "\U000F1788",
"progress-star-four-points": "\U000F1C3D",
"progress-tag": "\U000F1D0D",
"progress-upload": "\U000F0998",
"progress-wrench": "\U000F0CBD",
"projector": "\U000F042E",
@ -5531,6 +5660,7 @@ md_icons = {
"quality-high": "\U000F0435",
"quality-low": "\U000F0A0C",
"quality-medium": "\U000F0A0D",
"queue-first-in-last-out": "\U000F1CAF",
"quora": "\U000F0D29",
"rabbit": "\U000F0907",
"rabbit-variant": "\U000F1A61",
@ -5779,6 +5909,7 @@ md_icons = {
"rounded-corner": "\U000F0607",
"router": "\U000F11E2",
"router-network": "\U000F1087",
"router-network-wireless": "\U000F1C97",
"router-wireless": "\U000F0469",
"router-wireless-off": "\U000F15A3",
"router-wireless-settings": "\U000F0A69",
@ -5923,10 +6054,14 @@ md_icons = {
"serial-port": "\U000F065C",
"server": "\U000F048B",
"server-minus": "\U000F048C",
"server-minus-outline": "\U000F1C98",
"server-network": "\U000F048D",
"server-network-off": "\U000F048E",
"server-network-outline": "\U000F1C99",
"server-off": "\U000F048F",
"server-outline": "\U000F1C9A",
"server-plus": "\U000F0490",
"server-plus-outline": "\U000F1C9B",
"server-remove": "\U000F0491",
"server-security": "\U000F0492",
"set-all": "\U000F0778",
@ -6466,6 +6601,7 @@ md_icons = {
"swap-horizontal-bold": "\U000F0BCD",
"swap-horizontal-circle": "\U000F0FE1",
"swap-horizontal-circle-outline": "\U000F0FE2",
"swap-horizontal-hidden": "\U000F1D0E",
"swap-horizontal-variant": "\U000F08C1",
"swap-vertical": "\U000F04E2",
"swap-vertical-bold": "\U000F0BCE",
@ -6563,6 +6699,8 @@ md_icons = {
"tag-arrow-up-outline": "\U000F1732",
"tag-check": "\U000F1A7A",
"tag-check-outline": "\U000F1A7B",
"tag-edit": "\U000F1C9C",
"tag-edit-outline": "\U000F1C9D",
"tag-faces": "\U000F04FA",
"tag-heart": "\U000F068B",
"tag-heart-outline": "\U000F0BCF",
@ -6838,6 +6976,7 @@ md_icons = {
"traffic-light": "\U000F052B",
"traffic-light-outline": "\U000F182A",
"train": "\U000F052C",
"train-bus": "\U000F1CC7",
"train-car": "\U000F0BD8",
"train-car-autorack": "\U000F1B2D",
"train-car-box": "\U000F1B2E",
@ -6931,6 +7070,8 @@ md_icons = {
"truck-flatbed": "\U000F1891",
"truck-minus": "\U000F19AE",
"truck-minus-outline": "\U000F19BD",
"truck-off-road": "\U000F1C9E",
"truck-off-road-off": "\U000F1C9F",
"truck-outline": "\U000F129D",
"truck-plus": "\U000F19AD",
"truck-plus-outline": "\U000F19BC",
@ -6975,6 +7116,7 @@ md_icons = {
"umbrella-closed-outline": "\U000F13E2",
"umbrella-closed-variant": "\U000F13E1",
"umbrella-outline": "\U000F054B",
"underwear-outline": "\U000F1D0F",
"undo": "\U000F054C",
"undo-variant": "\U000F054D",
"unfold-less-horizontal": "\U000F054E",
@ -6990,15 +7132,21 @@ md_icons = {
"unreal": "\U000F09B1",
"update": "\U000F06B0",
"upload": "\U000F0552",
"upload-box": "\U000F1D10",
"upload-box-outline": "\U000F1D11",
"upload-circle": "\U000F1D12",
"upload-circle-outline": "\U000F1D13",
"upload-lock": "\U000F1373",
"upload-lock-outline": "\U000F1374",
"upload-multiple": "\U000F083D",
"upload-multiple-outline": "\U000F1D14",
"upload-network": "\U000F06F6",
"upload-network-outline": "\U000F0CD8",
"upload-off": "\U000F10C6",
"upload-off-outline": "\U000F10C7",
"upload-outline": "\U000F0E07",
"usb": "\U000F0553",
"usb-c-port": "\U000F1CBF",
"usb-flash-drive": "\U000F129E",
"usb-flash-drive-outline": "\U000F129F",
"usb-port": "\U000F11F0",
@ -7083,6 +7231,7 @@ md_icons = {
"video-plus": "\U000F09B3",
"video-plus-outline": "\U000F01D3",
"video-stabilization": "\U000F091B",
"video-standard-definition": "\U000F1CA0",
"video-switch": "\U000F0569",
"video-switch-outline": "\U000F0790",
"video-vintage": "\U000F0A1C",
@ -7233,6 +7382,9 @@ md_icons = {
"watering-can-outline": "\U000F1482",
"watermark": "\U000F0612",
"wave": "\U000F0F2E",
"wave-arrow-down": "\U000F1CB0",
"wave-arrow-up": "\U000F1CB1",
"wave-undercurrent": "\U000F1CC0",
"waveform": "\U000F147D",
"waves": "\U000F078D",
"waves-arrow-left": "\U000F1859",
@ -7251,6 +7403,9 @@ md_icons = {
"weather-hurricane-outline": "\U000F1C78",
"weather-lightning": "\U000F0593",
"weather-lightning-rainy": "\U000F067E",
"weather-moonset": "\U000F1D15",
"weather-moonset-down": "\U000F1D16",
"weather-moonset-up": "\U000F1D17",
"weather-night": "\U000F0594",
"weather-night-partly-cloudy": "\U000F0F31",
"weather-partly-cloudy": "\U000F0595",
@ -7424,23 +7579,27 @@ md_icons = {
if __name__ == "__main__":
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.screenmanager import Screen
from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
from kivymd.uix.list import OneLineIconListItem
from kivymd.uix.list import MDListItem
Builder.load_string(
"""
#:import images_path kivymd.images_path
<CustomOneLineIconListItem>
<IconItem>
IconLeftWidget:
MDListItemLeadingIcon:
icon: root.icon
MDListItemSupportingText:
text: root.text
<PreviousMDIcons>
md_bg_color: self.theme_cls.backgroundColor
MDBoxLayout:
orientation: 'vertical'
@ -7452,6 +7611,7 @@ if __name__ == "__main__":
MDIconButton:
icon: 'magnify'
pos_hint: {'center_y': .5}
MDTextField:
id: search_field
@ -7464,7 +7624,7 @@ if __name__ == "__main__":
key_size: 'height'
RecycleBoxLayout:
padding: dp(10)
padding: dp(10), dp(10), 0, dp(10)
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
@ -7473,17 +7633,18 @@ if __name__ == "__main__":
"""
)
class CustomOneLineIconListItem(OneLineIconListItem):
class IconItem(MDListItem):
icon = StringProperty()
text = StringProperty()
class PreviousMDIcons(Screen):
class PreviousMDIcons(MDScreen):
def set_list_md_icons(self, text="", search=False):
"""Builds a list of icons for the screen MDIcons."""
def add_icon_item(name_icon):
self.ids.rv.data.append(
{
"viewclass": "CustomOneLineIconListItem",
"viewclass": "IconItem",
"icon": name_icon,
"text": name_icon,
"callback": lambda x: x,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

View file

@ -21,44 +21,3 @@ elif Window.width >= dp(600) and Window.height >= dp(600):
DEVICE_TYPE = "tablet"
else:
DEVICE_TYPE = "mobile"
if DEVICE_TYPE == "mobile":
MAX_NAV_DRAWER_WIDTH = dp(300)
HORIZ_MARGINS = dp(16)
STANDARD_INCREMENT = dp(56)
PORTRAIT_TOOLBAR_HEIGHT = STANDARD_INCREMENT
LANDSCAPE_TOOLBAR_HEIGHT = STANDARD_INCREMENT - dp(8)
else:
MAX_NAV_DRAWER_WIDTH = dp(400)
HORIZ_MARGINS = dp(24)
STANDARD_INCREMENT = dp(64)
PORTRAIT_TOOLBAR_HEIGHT = STANDARD_INCREMENT
LANDSCAPE_TOOLBAR_HEIGHT = STANDARD_INCREMENT
# Elevation.
SEGMENT_CONTROL_SEGMENT_SWITCH_ELEVATION = 1
FILE_MANAGER_TOP_APP_BAR_ELEVATION = 1
FLOATING_ACTION_BUTTON_M2_ELEVATION = 1
FLOATING_ACTION_BUTTON_M3_ELEVATION = 0.5
CARD_STYLE_ELEVATED_M3_ELEVATION = 0.5
CARD_STYLE_OUTLINED_FILLED_M3_ELEVATION = 0
DATA_TABLE_ELEVATION = 4
DROP_DOWN_MENU_ELEVATION = 2
TOP_APP_BAR_ELEVATION = 2
SNACK_BAR_ELEVATION = 2
# Shadow softness.
RAISED_BUTTON_SOFTNESS = 4
FLOATING_ACTION_BUTTON_M3_SOFTNESS = 0
DATA_TABLE_SOFTNESS = 12
DROP_DOWN_MENU_SOFTNESS = 6
# Shadow offset.
RAISED_BUTTON_OFFSET = (0, -2)
FLOATING_ACTION_BUTTON_M2_OFFSET = (0, -1)
FLOATING_ACTION_BUTTON_M3_OFFSET = (0, -2)
DATA_TABLE_OFFSET = (0, -2)
DROP_DOWN_MENU_OFFSET = (0, -2)
SNACK_BAR_OFFSET = (0, -2)
TOUCH_TARGET_HEIGHT = dp(48)

File diff suppressed because it is too large Load diff

View file

@ -1,90 +0,0 @@
"""
Theming Dynamic Text
====================
Two implementations. The first is based on color brightness obtained from-
https://www.w3.org/TR/AERT#color-contrast
The second is based on relative luminance calculation for sRGB obtained from-
https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
and contrast ratio calculation obtained from-
https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
Preliminary testing suggests color brightness more closely matches the
`Material Design spec` suggested text colors, but the alternative implementation
is both newer and the current 'correct' recommendation, so is included here
as an option.
"""
def _color_brightness(color):
# Implementation of color brightness method
brightness = color[0] * 299 + color[1] * 587 + color[2] * 114
brightness = brightness
return brightness
def _black_or_white_by_color_brightness(color):
if _color_brightness(color) >= 500:
return "black"
else:
return "white"
def _normalized_channel(color):
# Implementation of contrast ratio and relative luminance method
if color <= 0.03928:
return color / 12.92
else:
return ((color + 0.055) / 1.055) ** 2.4
def _luminance(color):
rg = _normalized_channel(color[0])
gg = _normalized_channel(color[1])
bg = _normalized_channel(color[2])
return 0.2126 * rg + 0.7152 * gg + 0.0722 * bg
def _black_or_white_by_contrast_ratio(color):
l_color = _luminance(color)
l_black = 0.0
l_white = 1.0
b_contrast = (l_color + 0.05) / (l_black + 0.05)
w_contrast = (l_white + 0.05) / (l_color + 0.05)
return "white" if w_contrast >= b_contrast else "black"
def get_contrast_text_color(color, use_color_brightness=True):
if use_color_brightness:
contrast_color = _black_or_white_by_color_brightness(color)
else:
contrast_color = _black_or_white_by_contrast_ratio(color)
if contrast_color == "white":
return 1, 1, 1, 1
else:
return 0, 0, 0, 1
if __name__ == "__main__":
from kivy.utils import get_color_from_hex
from kivymd.color_definitions import colors, text_colors
for c in colors.items():
if c[0] in ["Light", "Dark"]:
continue
color = c[0]
print(f"For the {color} color palette:")
for name, hex_color in c[1].items():
if hex_color:
col = get_color_from_hex(hex_color)
col_bri = get_contrast_text_color(col)
con_rat = get_contrast_text_color(
col, use_color_brightness=False
)
text_color = text_colors[c[0]][name]
print(
f" The {name} hue gives {col_bri} using color "
f"brightness, {con_rat} using contrast ratio, and "
f"{text_color} from the MD spec"
)

View file

@ -1,11 +1,3 @@
__all__ = ("toast",)
from kivy.utils import platform
if platform == "android":
try:
from .androidtoast import toast
except ModuleNotFoundError:
from .kivytoast import toast
else:
from .kivytoast import toast
from .androidtoast import toast

View file

@ -8,26 +8,27 @@ AndroidToast
# Will be automatically used native implementation of the toast
# if your application is running on an Android device.
# Otherwise, will be used toast implementation
# from the kivymd/toast/kivytoast package.
# On desktop use `MDSnackbar < https://kivymd.readthedocs.io/en/latest/components/snackbar/>`_
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivymd.toast import toast
from kivymd.app import MDApp
KV = '''
MDScreen:
md_bg_color: self.theme_cls.backgroundColor
MDFlatButton:
text: "My Toast"
MDButton:
pos_hint:{"center_x": .5, "center_y": .5}
on_press: app.show_toast()
MDButtonText:
text: "Make toast"
'''
class Test(MDApp):
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
@ -35,7 +36,7 @@ AndroidToast
toast("Hello World", True, 80, 200, 0)
Test().run()
Example().run()
"""
__all__ = ("toast",)
@ -47,10 +48,10 @@ if platform != "android":
f"{platform.capitalize()} platform does not support Android Toast"
)
from android import mActivity
from android.runnable import run_on_ui_thread
from jnius import autoclass
activity = autoclass("org.kivy.android.PythonActivity").mActivity
Toast = autoclass("android.widget.Toast")
String = autoclass("java.lang.String")
@ -63,7 +64,7 @@ def toast(text, length_long=False, gravity=0, y=0, x=0):
:param length_long: the amount of time (in seconds) that the toast is
visible on the screen;
:param text: text to be displayed in the toast;
:param short_duration: duration of the toast, if `True` the toast
:param length_long: duration of the toast, if `True` the toast
will last 2.3s but if it is `False` the toast will last 3.9s;
:param gravity: refers to the toast position, if it is 80 the toast will
be shown below, if it is 40 the toast will be displayed above;
@ -76,6 +77,6 @@ def toast(text, length_long=False, gravity=0, y=0, x=0):
"""
duration = Toast.LENGTH_SHORT if length_long else Toast.LENGTH_LONG
t = Toast.makeText(activity, String(text), duration)
t = Toast.makeText(mActivity, String(text), duration)
t.setGravity(gravity, x, y)
t.show()

View file

@ -1,12 +0,0 @@
"""
Toast for Android device
========================
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/toast.png
:align: center
"""
__all__ = ("toast",)
from .androidtoast import toast

View file

@ -1,3 +0,0 @@
__all__ = ("toast",)
from .kivytoast import toast

View file

@ -1,154 +0,0 @@
"""
KivyToast
=========
.. rubric:: Implementation of toasts for desktop.
.. code-block:: python
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.toast import toast
KV = '''
MDScreen:
MDTopAppBar:
title: 'Test Toast'
pos_hint: {'top': 1}
left_action_items: [['menu', lambda x: x]]
MDRaisedButton:
text: 'TEST KIVY TOAST'
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.show_toast()
'''
class Test(MDApp):
def show_toast(self):
'''Displays a toast on the screen.'''
toast('Test Kivy Toast')
def build(self):
return Builder.load_string(KV)
Test().run()
"""
from typing import List
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import ListProperty, NumericProperty
from kivy.uix.label import Label
from kivymd.uix.dialog import BaseDialog
Builder.load_string(
"""
<Toast>:
size_hint: (None, None)
pos_hint: {"center_x": 0.5, "center_y": 0.1}
opacity: 0
auto_dismiss: True
overlay_color: [0, 0, 0, 0]
canvas:
Color:
rgba: root._md_bg_color
RoundedRectangle:
pos: self.pos
size: self.size
radius: root.radius
"""
)
class Toast(BaseDialog):
duration = NumericProperty(2.5)
"""
The amount of time (in seconds) that the toast is visible on the screen.
:attr:`duration` is an :class:`~kivy.properties.NumericProperty`
and defaults to `2.5`.
"""
_md_bg_color = ListProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.label_toast = Label(size_hint=(None, None), markup=True, opacity=0)
self.label_toast.bind(texture_size=self.label_check_texture_size)
self.add_widget(self.label_toast)
def label_check_texture_size(
self, instance_label: Label, texture_size: List[int]
) -> None:
"""
Resizes the text if the text texture is larger than the screen size.
Sets the size of the toast according to the texture size of the toast
text.
"""
texture_width, texture_height = texture_size
if texture_width > Window.width:
instance_label.text_size = (Window.width - dp(10), None)
instance_label.texture_update()
texture_width, texture_height = instance_label.texture_size
self.size = (texture_width + 25, texture_height + 25)
def toast(self, text_toast: str) -> None:
"""Displays a toast."""
self.label_toast.text = text_toast
self.open()
def on_open(self) -> None:
"""Default open event handler."""
self.fade_in()
Clock.schedule_once(self.fade_out, self.duration)
def fade_in(self) -> None:
"""Animation of opening toast on the screen."""
anim = Animation(opacity=1, duration=0.4)
anim.start(self.label_toast)
anim.start(self)
def fade_out(self, *args) -> None:
"""Animation of hiding toast on the screen."""
anim = Animation(opacity=0, duration=0.4)
anim.bind(on_complete=lambda *x: self.dismiss())
anim.start(self.label_toast)
anim.start(self)
def on_touch_down(self, touch):
if not self.collide_point(*touch.pos):
if self.auto_dismiss:
self.fade_out()
return False
super().on_touch_down(touch)
return True
def toast(
text: str = "", background: list = None, duration: float = 2.5
) -> None:
"""
Displays a toast.
:param text: text to be displayed in the toast;
:param duration: the amount of time (in seconds) that the toast is visible on the screen
:param background: toast background color in ``rgba`` format;
"""
if background is None:
background = [0.2, 0.2, 0.2, 1]
Toast(duration=duration, _md_bg_color=background).toast(text)

View file

@ -5,10 +5,8 @@ from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen
from kivymd.uix.behaviors import SpecificBackgroundColorBehavior
class MDAdaptiveWidget(SpecificBackgroundColorBehavior):
class MDAdaptiveWidget:
adaptive_height = BooleanProperty(False)
"""
If `True`, the following properties will be applied to the widget:

Some files were not shown because too many files have changed in this diff Show more