908 lines
29 KiB
Python
Executable file
908 lines
29 KiB
Python
Executable file
"""
|
||
Themes/Theming
|
||
==============
|
||
|
||
.. seealso::
|
||
|
||
`Material Design spec, Material theming <https://material.io/design/material-theming>`_
|
||
|
||
Material App
|
||
------------
|
||
|
||
The main class of your application, which in `Kivy` inherits from the App class,
|
||
in `KivyMD` must inherit from the `MDApp` class. The `MDApp` class has
|
||
properties that allow you to control application properties
|
||
such as :attr:`color/style/font` of interface elements and much more.
|
||
|
||
Control material properties
|
||
---------------------------
|
||
|
||
The main application class inherited from the `MDApp` class has the :attr:`theme_cls`
|
||
attribute, with which you control the material properties of your application.
|
||
"""
|
||
|
||
from kivy.app import App
|
||
from kivy.atlas import Atlas
|
||
from kivy.clock import Clock
|
||
from kivy.core.window import Window
|
||
from kivy.event import EventDispatcher
|
||
from kivy.metrics import dp
|
||
from kivy.properties import (
|
||
AliasProperty,
|
||
BooleanProperty,
|
||
DictProperty,
|
||
ListProperty,
|
||
ObjectProperty,
|
||
OptionProperty,
|
||
StringProperty,
|
||
)
|
||
from kivy.utils import get_color_from_hex
|
||
|
||
from kivymd import images_path
|
||
from kivymd.color_definitions import colors, hue, palette
|
||
from kivymd.material_resources import DEVICE_IOS, DEVICE_TYPE
|
||
|
||
from kivymd.font_definitions import theme_font_styles # NOQA: F401
|
||
|
||
|
||
class ThemeManager(EventDispatcher):
|
||
primary_palette = OptionProperty("Blue", options=palette)
|
||
"""
|
||
The name of the color scheme that the application will use.
|
||
All major `material` components will have the color
|
||
of the specified color theme.
|
||
|
||
Available options are: `'Red'`, `'Pink'`, `'Purple'`, `'DeepPurple'`,
|
||
`'Indigo'`, `'Blue'`, `'LightBlue'`, `'Cyan'`, `'Teal'`, `'Green'`,
|
||
`'LightGreen'`, `'Lime'`, `'Yellow'`, `'Amber'`, `'Orange'`, `'DeepOrange'`,
|
||
`'Brown'`, `'Gray'`, `'BlueGray'`.
|
||
|
||
To change the color scheme of an application:
|
||
|
||
.. code-block:: python
|
||
|
||
from kivy.uix.screenmanager import Screen
|
||
|
||
from kivymd.app import MDApp
|
||
from kivymd.uix.button import MDRectangleFlatButton
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
self.theme_cls.primary_palette = "Green" # "Purple", "Red"
|
||
|
||
screen = Screen()
|
||
screen.add_widget(
|
||
MDRectangleFlatButton(
|
||
text="Hello, World",
|
||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
||
)
|
||
)
|
||
return screen
|
||
|
||
|
||
MainApp().run()
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-palette.png
|
||
|
||
:attr:`primary_palette` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'Blue'`.
|
||
"""
|
||
|
||
primary_hue = OptionProperty("500", options=hue)
|
||
"""
|
||
The color hue of the application.
|
||
|
||
Available options are: `'50'`, `'100'`, `'200'`, `'300'`, `'400'`, `'500'`,
|
||
`'600'`, `'700'`, `'800'`, `'900'`, `'A100'`, `'A200'`, `'A400'`, `'A700'`.
|
||
|
||
To change the hue color scheme of an application:
|
||
|
||
.. code-block:: python
|
||
|
||
from kivy.uix.screenmanager import Screen
|
||
|
||
from kivymd.app import MDApp
|
||
from kivymd.uix.button import MDRectangleFlatButton
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
self.theme_cls.primary_palette = "Green" # "Purple", "Red"
|
||
self.theme_cls.primary_hue = "200" # "500"
|
||
|
||
screen = Screen()
|
||
screen.add_widget(
|
||
MDRectangleFlatButton(
|
||
text="Hello, World",
|
||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
||
)
|
||
)
|
||
return screen
|
||
|
||
|
||
MainApp().run()
|
||
|
||
With a value of ``self.theme_cls.primary_hue = "500"``:
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-palette.png
|
||
|
||
With a value of ``self.theme_cls.primary_hue = "200"``:
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-hue.png
|
||
|
||
:attr:`primary_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'500'`.
|
||
"""
|
||
|
||
primary_light_hue = OptionProperty("200", options=hue)
|
||
"""
|
||
Hue value for :attr:`primary_light`.
|
||
|
||
:attr:`primary_light_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'200'`.
|
||
"""
|
||
|
||
primary_dark_hue = OptionProperty("700", options=hue)
|
||
"""
|
||
Hue value for :attr:`primary_dark`.
|
||
|
||
:attr:`primary_light_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'700'`.
|
||
"""
|
||
|
||
def _get_primary_color(self):
|
||
return get_color_from_hex(
|
||
colors[self.primary_palette][self.primary_hue]
|
||
)
|
||
|
||
primary_color = AliasProperty(
|
||
_get_primary_color, bind=("primary_palette", "primary_hue")
|
||
)
|
||
"""
|
||
The color of the current application theme in ``rgba`` format.
|
||
|
||
:attr:`primary_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value of the current application theme, property is readonly.
|
||
"""
|
||
|
||
def _get_primary_light(self):
|
||
return get_color_from_hex(
|
||
colors[self.primary_palette][self.primary_light_hue]
|
||
)
|
||
|
||
primary_light = AliasProperty(
|
||
_get_primary_light, bind=("primary_palette", "primary_light_hue")
|
||
)
|
||
"""
|
||
Colors of the current application color theme in ``rgba`` format
|
||
(in lighter color).
|
||
|
||
.. code-block:: python
|
||
|
||
from kivy.lang import Builder
|
||
|
||
from kivymd.app import MDApp
|
||
|
||
|
||
KV = '''
|
||
Screen:
|
||
|
||
MDRaisedButton:
|
||
text: "primary_light"
|
||
pos_hint: {"center_x": 0.5, "center_y": 0.7}
|
||
md_bg_color: app.theme_cls.primary_light
|
||
|
||
MDRaisedButton:
|
||
text: "primary_color"
|
||
pos_hint: {"center_x": 0.5, "center_y": 0.5}
|
||
|
||
MDRaisedButton:
|
||
text: "primary_dark"
|
||
pos_hint: {"center_x": 0.5, "center_y": 0.3}
|
||
md_bg_color: app.theme_cls.primary_dark
|
||
'''
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
self.theme_cls.primary_palette = "Green"
|
||
return Builder.load_string(KV)
|
||
|
||
|
||
MainApp().run()
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/primary-colors-light-dark.png
|
||
:align: center
|
||
|
||
:attr:`primary_light` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value of the current application theme (in lighter color),
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_primary_dark(self):
|
||
return get_color_from_hex(
|
||
colors[self.primary_palette][self.primary_dark_hue]
|
||
)
|
||
|
||
primary_dark = AliasProperty(
|
||
_get_primary_dark, bind=("primary_palette", "primary_dark_hue")
|
||
)
|
||
"""
|
||
Colors of the current application color theme
|
||
in ``rgba`` format (in darker color).
|
||
|
||
:attr:`primary_dark` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value of the current application theme (in darker color),
|
||
property is readonly.
|
||
"""
|
||
|
||
accent_palette = OptionProperty("Amber", options=palette)
|
||
"""
|
||
The application color palette used for items such as the tab indicator
|
||
in the :attr:`MDTabsBar` class and so on...
|
||
|
||
The image below shows the color schemes with the values
|
||
``self.theme_cls.accent_palette = 'Blue'``, ``Red'`` and ``Yellow'``:
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/accent-palette.png
|
||
|
||
:attr:`primary_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'Amber'`.
|
||
"""
|
||
|
||
accent_hue = OptionProperty("500", options=hue)
|
||
"""Similar to :attr:`primary_hue`,
|
||
but returns a value for :attr:`accent_palette`.
|
||
|
||
:attr:`accent_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'500'`.
|
||
"""
|
||
|
||
accent_light_hue = OptionProperty("200", options=hue)
|
||
"""
|
||
Hue value for :attr:`accent_light`.
|
||
|
||
:attr:`accent_light_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'200'`.
|
||
"""
|
||
|
||
accent_dark_hue = OptionProperty("700", options=hue)
|
||
"""
|
||
Hue value for :attr:`accent_dark`.
|
||
|
||
:attr:`accent_dark_hue` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'700'`.
|
||
"""
|
||
|
||
def _get_accent_color(self):
|
||
return get_color_from_hex(colors[self.accent_palette][self.accent_hue])
|
||
|
||
accent_color = AliasProperty(
|
||
_get_accent_color, bind=["accent_palette", "accent_hue"]
|
||
)
|
||
"""Similar to :attr:`primary_color`,
|
||
but returns a value for :attr:`accent_color`.
|
||
|
||
:attr:`accent_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`accent_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_accent_light(self):
|
||
return get_color_from_hex(
|
||
colors[self.accent_palette][self.accent_light_hue]
|
||
)
|
||
|
||
accent_light = AliasProperty(
|
||
_get_accent_light, bind=["accent_palette", "accent_light_hue"]
|
||
)
|
||
"""Similar to :attr:`primary_light`,
|
||
but returns a value for :attr:`accent_light`.
|
||
|
||
:attr:`accent_light` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`accent_light`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_accent_dark(self):
|
||
return get_color_from_hex(
|
||
colors[self.accent_palette][self.accent_dark_hue]
|
||
)
|
||
|
||
accent_dark = AliasProperty(
|
||
_get_accent_dark, bind=["accent_palette", "accent_dark_hue"]
|
||
)
|
||
"""Similar to :attr:`primary_dark`,
|
||
but returns a value for :attr:`accent_dark`.
|
||
|
||
:attr:`accent_dark` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`accent_dark`,
|
||
property is readonly.
|
||
"""
|
||
|
||
theme_style = OptionProperty("Light", options=["Light", "Dark"])
|
||
"""App theme style.
|
||
|
||
.. code-block:: python
|
||
|
||
from kivy.uix.screenmanager import Screen
|
||
|
||
from kivymd.app import MDApp
|
||
from kivymd.uix.button import MDRectangleFlatButton
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
self.theme_cls.theme_style = "Dark" # "Light"
|
||
|
||
screen = Screen()
|
||
screen.add_widget(
|
||
MDRectangleFlatButton(
|
||
text="Hello, World",
|
||
pos_hint={"center_x": 0.5, "center_y": 0.5},
|
||
)
|
||
)
|
||
return screen
|
||
|
||
|
||
MainApp().run()
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/theme-style.png
|
||
|
||
:attr:`theme_style` is an :class:`~kivy.properties.OptionProperty`
|
||
and defaults to `'Light'`.
|
||
"""
|
||
|
||
def _get_theme_style(self, opposite):
|
||
if opposite:
|
||
return "Light" if self.theme_style == "Dark" else "Dark"
|
||
else:
|
||
return self.theme_style
|
||
|
||
def _get_bg_darkest(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
return get_color_from_hex(colors["Light"]["StatusBar"])
|
||
elif theme_style == "Dark":
|
||
return get_color_from_hex(colors["Dark"]["StatusBar"])
|
||
|
||
bg_darkest = AliasProperty(_get_bg_darkest, bind=["theme_style"])
|
||
"""
|
||
Similar to :attr:`bg_dark`,
|
||
but the color values are a tone lower (darker) than :attr:`bg_dark`.
|
||
|
||
.. code-block:: python
|
||
|
||
KV = '''
|
||
<Box@BoxLayout>:
|
||
bg: 0, 0, 0, 0
|
||
|
||
canvas:
|
||
Color:
|
||
rgba: root.bg
|
||
Rectangle:
|
||
pos: self.pos
|
||
size: self.size
|
||
|
||
BoxLayout:
|
||
|
||
Box:
|
||
bg: app.theme_cls.bg_light
|
||
Box:
|
||
bg: app.theme_cls.bg_normal
|
||
Box:
|
||
bg: app.theme_cls.bg_dark
|
||
Box:
|
||
bg: app.theme_cls.bg_darkest
|
||
'''
|
||
|
||
from kivy.lang import Builder
|
||
|
||
from kivymd.app import MDApp
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
self.theme_cls.theme_style = "Dark" # "Light"
|
||
return Builder.load_string(KV)
|
||
|
||
|
||
MainApp().run()
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/bg-normal-dark-darkest.png
|
||
|
||
:attr:`bg_darkest` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`bg_darkest`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_bg_darkest(self):
|
||
return self._get_bg_darkest(True)
|
||
|
||
opposite_bg_darkest = AliasProperty(
|
||
_get_op_bg_darkest, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`bg_darkest`.
|
||
|
||
:attr:`opposite_bg_darkest` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_bg_darkest`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_bg_dark(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
return get_color_from_hex(colors["Light"]["AppBar"])
|
||
elif theme_style == "Dark":
|
||
return get_color_from_hex(colors["Dark"]["AppBar"])
|
||
|
||
bg_dark = AliasProperty(_get_bg_dark, bind=["theme_style"])
|
||
"""
|
||
Similar to :attr:`bg_normal`,
|
||
but the color values are one tone lower (darker) than :attr:`bg_normal`.
|
||
|
||
:attr:`bg_dark` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`bg_dark`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_bg_dark(self):
|
||
return self._get_bg_dark(True)
|
||
|
||
opposite_bg_dark = AliasProperty(_get_op_bg_dark, bind=["theme_style"])
|
||
"""
|
||
The opposite value of color in the :attr:`bg_dark`.
|
||
|
||
:attr:`opposite_bg_dark` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`opposite_bg_dark`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_bg_normal(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
return get_color_from_hex(colors["Light"]["Background"])
|
||
elif theme_style == "Dark":
|
||
return get_color_from_hex(colors["Dark"]["Background"])
|
||
|
||
bg_normal = AliasProperty(_get_bg_normal, bind=["theme_style"])
|
||
"""
|
||
Similar to :attr:`bg_light`,
|
||
but the color values are one tone lower (darker) than :attr:`bg_light`.
|
||
|
||
:attr:`bg_normal` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`bg_normal`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_bg_normal(self):
|
||
return self._get_bg_normal(True)
|
||
|
||
opposite_bg_normal = AliasProperty(_get_op_bg_normal, bind=["theme_style"])
|
||
"""
|
||
The opposite value of color in the :attr:`bg_normal`.
|
||
|
||
:attr:`opposite_bg_normal` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_bg_normal`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_bg_light(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
return get_color_from_hex(colors["Light"]["CardsDialogs"])
|
||
elif theme_style == "Dark":
|
||
return get_color_from_hex(colors["Dark"]["CardsDialogs"])
|
||
|
||
bg_light = AliasProperty(_get_bg_light, bind=["theme_style"])
|
||
""""
|
||
Depending on the style of the theme (`'Dark'` or `'Light`')
|
||
that the application uses, :attr:`bg_light` contains the color value
|
||
in ``rgba`` format for the widgets background.
|
||
|
||
:attr:`bg_light` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`bg_light`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_bg_light(self):
|
||
return self._get_bg_light(True)
|
||
|
||
opposite_bg_light = AliasProperty(_get_op_bg_light, bind=["theme_style"])
|
||
"""
|
||
The opposite value of color in the :attr:`bg_light`.
|
||
|
||
:attr:`opposite_bg_light` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_bg_light`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_divider_color(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
color = get_color_from_hex("000000")
|
||
elif theme_style == "Dark":
|
||
color = get_color_from_hex("FFFFFF")
|
||
color[3] = 0.12
|
||
return color
|
||
|
||
divider_color = AliasProperty(_get_divider_color, bind=["theme_style"])
|
||
"""
|
||
Color for dividing lines such as :class:`~kivymd.uix.card.MDSeparator`.
|
||
|
||
:attr:`divider_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`divider_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_divider_color(self):
|
||
return self._get_divider_color(True)
|
||
|
||
opposite_divider_color = AliasProperty(
|
||
_get_op_divider_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`divider_color`.
|
||
|
||
:attr:`opposite_divider_color` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_divider_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_text_color(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
color = get_color_from_hex("000000")
|
||
color[3] = 0.87
|
||
elif theme_style == "Dark":
|
||
color = get_color_from_hex("FFFFFF")
|
||
return color
|
||
|
||
text_color = AliasProperty(_get_text_color, bind=["theme_style"])
|
||
"""
|
||
Color of the text used in the :class:`~kivymd.uix.label.MDLabel`.
|
||
|
||
:attr:`text_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_text_color(self):
|
||
return self._get_text_color(True)
|
||
|
||
opposite_text_color = AliasProperty(
|
||
_get_op_text_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`text_color`.
|
||
|
||
:attr:`opposite_text_color` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_secondary_text_color(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
color = get_color_from_hex("000000")
|
||
color[3] = 0.54
|
||
elif theme_style == "Dark":
|
||
color = get_color_from_hex("FFFFFF")
|
||
color[3] = 0.70
|
||
return color
|
||
|
||
secondary_text_color = AliasProperty(
|
||
_get_secondary_text_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The color for the secondary text that is used in classes
|
||
from the module :class:`~kivymd/uix/list.TwoLineListItem`.
|
||
|
||
:attr:`secondary_text_color` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`secondary_text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_secondary_text_color(self):
|
||
return self._get_secondary_text_color(True)
|
||
|
||
opposite_secondary_text_color = AliasProperty(
|
||
_get_op_secondary_text_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`secondary_text_color`.
|
||
|
||
:attr:`opposite_secondary_text_color`
|
||
is an :class:`~kivy.properties.AliasProperty` that returns the value
|
||
in ``rgba`` format for :attr:`opposite_secondary_text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_icon_color(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
color = get_color_from_hex("000000")
|
||
color[3] = 0.54
|
||
elif theme_style == "Dark":
|
||
color = get_color_from_hex("FFFFFF")
|
||
return color
|
||
|
||
icon_color = AliasProperty(_get_icon_color, bind=["theme_style"])
|
||
"""
|
||
Color of the icon used in the :class:`~kivymd.uix.button.MDIconButton`.
|
||
|
||
:attr:`icon_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`icon_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_icon_color(self):
|
||
return self._get_icon_color(True)
|
||
|
||
opposite_icon_color = AliasProperty(
|
||
_get_op_icon_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`icon_color`.
|
||
|
||
:attr:`opposite_icon_color` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`opposite_icon_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_disabled_hint_text_color(self, opposite=False):
|
||
theme_style = self._get_theme_style(opposite)
|
||
if theme_style == "Light":
|
||
color = get_color_from_hex("000000")
|
||
color[3] = 0.38
|
||
elif theme_style == "Dark":
|
||
color = get_color_from_hex("FFFFFF")
|
||
color[3] = 0.50
|
||
return color
|
||
|
||
disabled_hint_text_color = AliasProperty(
|
||
_get_disabled_hint_text_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
Color of the disabled text used in the :class:`~kivymd.uix.textfield.MDTextField`.
|
||
|
||
:attr:`disabled_hint_text_color`
|
||
is an :class:`~kivy.properties.AliasProperty` that returns the value
|
||
in ``rgba`` format for :attr:`disabled_hint_text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_op_disabled_hint_text_color(self):
|
||
return self._get_disabled_hint_text_color(True)
|
||
|
||
opposite_disabled_hint_text_color = AliasProperty(
|
||
_get_op_disabled_hint_text_color, bind=["theme_style"]
|
||
)
|
||
"""
|
||
The opposite value of color in the :attr:`disabled_hint_text_color`.
|
||
|
||
:attr:`opposite_disabled_hint_text_color`
|
||
is an :class:`~kivy.properties.AliasProperty` that returns the value
|
||
in ``rgba`` format for :attr:`opposite_disabled_hint_text_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
# Hardcoded because muh standard
|
||
def _get_error_color(self):
|
||
return get_color_from_hex(colors["Red"]["A700"])
|
||
|
||
error_color = AliasProperty(_get_error_color)
|
||
"""
|
||
Color of the error text used
|
||
in the :class:`~kivymd.uix.textfield.MDTextField`.
|
||
|
||
:attr:`error_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`error_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_ripple_color(self):
|
||
return self._ripple_color
|
||
|
||
def _set_ripple_color(self, value):
|
||
self._ripple_color = value
|
||
|
||
_ripple_color = ListProperty(get_color_from_hex(colors["Gray"]["400"]))
|
||
"""Private value."""
|
||
|
||
ripple_color = AliasProperty(
|
||
_get_ripple_color, _set_ripple_color, bind=["_ripple_color"]
|
||
)
|
||
"""
|
||
Color of ripple effects.
|
||
|
||
:attr:`ripple_color` is an :class:`~kivy.properties.AliasProperty` that
|
||
returns the value in ``rgba`` format for :attr:`ripple_color`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _determine_device_orientation(self, _, window_size):
|
||
if window_size[0] > window_size[1]:
|
||
self.device_orientation = "landscape"
|
||
elif window_size[1] >= window_size[0]:
|
||
self.device_orientation = "portrait"
|
||
|
||
device_orientation = StringProperty("")
|
||
"""
|
||
Device orientation.
|
||
|
||
:attr:`device_orientation` is an :class:`~kivy.properties.StringProperty`.
|
||
"""
|
||
|
||
def _get_standard_increment(self):
|
||
if DEVICE_TYPE == "mobile":
|
||
if self.device_orientation == "landscape":
|
||
return dp(48)
|
||
else:
|
||
return dp(56)
|
||
else:
|
||
return dp(64)
|
||
|
||
standard_increment = AliasProperty(
|
||
_get_standard_increment, bind=["device_orientation"]
|
||
)
|
||
"""
|
||
Value of standard increment.
|
||
|
||
:attr:`standard_increment` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`standard_increment`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def _get_horizontal_margins(self):
|
||
if DEVICE_TYPE == "mobile":
|
||
return dp(16)
|
||
else:
|
||
return dp(24)
|
||
|
||
horizontal_margins = AliasProperty(_get_horizontal_margins)
|
||
"""
|
||
Value of horizontal margins.
|
||
|
||
:attr:`horizontal_margins` is an :class:`~kivy.properties.AliasProperty`
|
||
that returns the value in ``rgba`` format for :attr:`horizontal_margins`,
|
||
property is readonly.
|
||
"""
|
||
|
||
def on_theme_style(self, instance, value):
|
||
if (
|
||
hasattr(App.get_running_app(), "theme_cls")
|
||
and App.get_running_app().theme_cls == self
|
||
):
|
||
self.set_clearcolor_by_theme_style(value)
|
||
|
||
set_clearcolor = BooleanProperty(True)
|
||
|
||
def set_clearcolor_by_theme_style(self, theme_style):
|
||
if not self.set_clearcolor:
|
||
return
|
||
if theme_style == "Light":
|
||
Window.clearcolor = get_color_from_hex(
|
||
colors["Light"]["Background"]
|
||
)
|
||
elif theme_style == "Dark":
|
||
Window.clearcolor = get_color_from_hex(colors["Dark"]["Background"])
|
||
|
||
# font name, size (sp), always caps, letter spacing (sp)
|
||
font_styles = DictProperty(
|
||
{
|
||
"H1": ["RobotoLight", 96, False, -1.5],
|
||
"H2": ["RobotoLight", 60, False, -0.5],
|
||
"H3": ["Roboto", 48, False, 0],
|
||
"H4": ["Roboto", 34, False, 0.25],
|
||
"H5": ["Roboto", 24, False, 0],
|
||
"H6": ["RobotoMedium", 20, False, 0.15],
|
||
"Subtitle1": ["Roboto", 16, False, 0.15],
|
||
"Subtitle2": ["RobotoMedium", 14, False, 0.1],
|
||
"Body1": ["Roboto", 16, False, 0.5],
|
||
"Body2": ["Roboto", 14, False, 0.25],
|
||
"Button": ["RobotoMedium", 14, True, 1.25],
|
||
"Caption": ["Roboto", 12, False, 0.4],
|
||
"Overline": ["Roboto", 10, True, 1.5],
|
||
"Icon": ["Icons", 24, False, 0],
|
||
}
|
||
)
|
||
"""
|
||
Data of default font styles.
|
||
|
||
Add custom font:
|
||
|
||
.. code-block:: python
|
||
|
||
KV = '''
|
||
Screen:
|
||
|
||
MDLabel:
|
||
text: "JetBrainsMono"
|
||
halign: "center"
|
||
font_style: "JetBrainsMono"
|
||
'''
|
||
|
||
from kivy.core.text import LabelBase
|
||
|
||
from kivy.lang import Builder
|
||
|
||
from kivymd.app import MDApp
|
||
from kivymd.font_definitions import theme_font_styles
|
||
|
||
|
||
class MainApp(MDApp):
|
||
def build(self):
|
||
LabelBase.register(
|
||
name="JetBrainsMono",
|
||
fn_regular="JetBrainsMono-Regular.ttf")
|
||
|
||
theme_font_styles.append('JetBrainsMono')
|
||
self.theme_cls.font_styles["JetBrainsMono"] = [
|
||
"JetBrainsMono",
|
||
16,
|
||
False,
|
||
0.15,
|
||
]
|
||
return Builder.load_string(KV)
|
||
|
||
|
||
MainApp().run()
|
||
|
||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/font-styles.png
|
||
|
||
:attr:`font_styles` is an :class:`~kivy.properties.DictProperty`.
|
||
"""
|
||
|
||
def __init__(self, **kwargs):
|
||
super().__init__(**kwargs)
|
||
self.rec_shadow = Atlas(f"{images_path}rec_shadow.atlas")
|
||
self.rec_st_shadow = Atlas(f"{images_path}rec_st_shadow.atlas")
|
||
self.quad_shadow = Atlas(f"{images_path}quad_shadow.atlas")
|
||
self.round_shadow = Atlas(f"{images_path}round_shadow.atlas")
|
||
Clock.schedule_once(lambda x: self.on_theme_style(0, self.theme_style))
|
||
self._determine_device_orientation(None, Window.size)
|
||
Window.bind(size=self._determine_device_orientation)
|
||
|
||
|
||
class ThemableBehavior(EventDispatcher):
|
||
theme_cls = ObjectProperty()
|
||
"""
|
||
Instance of :class:`~ThemeManager` class.
|
||
|
||
:attr:`theme_cls` is an :class:`~kivy.properties.ObjectProperty`.
|
||
"""
|
||
|
||
device_ios = BooleanProperty(DEVICE_IOS)
|
||
"""
|
||
``True`` if device is ``iOS``.
|
||
|
||
:attr:`device_ios` is an :class:`~kivy.properties.BooleanProperty`.
|
||
"""
|
||
|
||
opposite_colors = BooleanProperty(False)
|
||
|
||
def __init__(self, **kwargs):
|
||
if self.theme_cls is not None:
|
||
pass
|
||
else:
|
||
try:
|
||
if not isinstance(
|
||
App.get_running_app().property("theme_cls", True),
|
||
ObjectProperty,
|
||
):
|
||
raise ValueError(
|
||
"KivyMD: App object must be inherited from "
|
||
"`kivymd.app.MDApp`. See "
|
||
"https://github.com/kivymd/KivyMD/blob/master/README.md#api-breaking-changes"
|
||
)
|
||
except AttributeError:
|
||
raise ValueError(
|
||
"KivyMD: App object must be initialized before loading "
|
||
"root widget. See "
|
||
"https://github.com/kivymd/KivyMD/wiki/Modules-Material-App#exceptions"
|
||
)
|
||
self.theme_cls = App.get_running_app().theme_cls
|
||
super().__init__(**kwargs)
|