separate_pages
quadrismegistus 4 years ago
parent 563fdd73d9
commit 60edbc00f0

1
.gitignore vendored

@ -0,0 +1 @@
__pycache__

@ -0,0 +1,80 @@
# See https://github.com/kivy/kivy/blob/master/.github/workflows/test_osx_python.yml
# Environment variables
echo "::set-env name=KIVY_GL_BACKEND::mock"
echo "::set-env name=CC::clang"
echo "::set-env name=CXX::clang"
echo "::set-env name=FFLAGS::-ff2c"
echo "::set-env name=USE_SDL2::1"
echo "::set-env name=USE_GSTREAMER::1"
# System dependencies
source .ci/macos_versions.sh
download_cache_curl() {
fname="$1"
key="$2"
url_prefix="$3"
if [ ! -f $key/$fname ]; then
if [ ! -d $key ]; then
mkdir "$key"
fi
curl -O -L "$url_prefix/$fname"
cp "$fname" "$key"
else
cp "$key/$fname" .
fi
}
download_cache_aria2() {
fname="$1"
key="$2"
url_prefix="$3"
if [ ! -f $key/$fname ]; then
if [ ! -d $key ]; then
mkdir "$key"
fi
/usr/local/aria2/bin/aria2c -x 10 "$url_prefix/$fname"
cp "$fname" "$key"
else
cp "$key/$fname" .
fi
}
download_cache_curl "aria2-$ARIAL2-osx-darwin.dmg" "macos-cache" "https://github.com/aria2/aria2/releases/download/release-$ARIAL2"
hdiutil attach aria2-$ARIAL2-osx-darwin.dmg
sudo installer -package "/Volumes/aria2 $ARIAL2 Intel/aria2.pkg" -target /
download_cache_curl "SDL2-$SDL2.dmg" "macos-cache" "https://www.libsdl.org/release"
download_cache_curl "SDL2_image-$SDL2_IMAGE.dmg" "macos-cache" "https://www.libsdl.org/projects/SDL_image/release"
download_cache_curl "SDL2_mixer-$SDL2_MIXER.dmg" "macos-cache" "https://www.libsdl.org/projects/SDL_mixer/release"
download_cache_curl "SDL2_ttf-$SDL2_TTF.dmg" "macos-cache" "https://www.libsdl.org/projects/SDL_ttf/release"
hdiutil attach SDL2-$SDL2.dmg
sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/
hdiutil attach SDL2_image-$SDL2_IMAGE.dmg
sudo cp -a /Volumes/SDL2_image/SDL2_image.framework /Library/Frameworks/
hdiutil attach SDL2_ttf-$SDL2_TTF.dmg
sudo cp -a /Volumes/SDL2_ttf/SDL2_ttf.framework /Library/Frameworks/
hdiutil attach SDL2_mixer-$SDL2_MIXER.dmg
sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/
download_cache_aria2 "gstreamer-1.0-$GSTREAMER-x86_64.pkg" "macos-cache" "https://gstreamer.freedesktop.org/data/pkg/osx/$GSTREAMER"
download_cache_aria2 "gstreamer-1.0-devel-$GSTREAMER-x86_64.pkg" "macos-cache-gst-devel" "https://gstreamer.freedesktop.org/data/pkg/osx/$GSTREAMER"
sudo installer -package gstreamer-1.0-$GSTREAMER-x86_64.pkg -target /
sudo installer -package gstreamer-1.0-devel-$GSTREAMER-x86_64.pkg -target /
# Pip dependencies
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade \
cython \
pytest pytest-cov pytest_asyncio pytest-timeout coveralls \
pillow docutils pygments pyinstaller \
sphinx sphinxcontrib-blockdiag sphinxcontrib-seqdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag
python -m pip install --upgrade kivy==$KIVY_VERSION

@ -0,0 +1,10 @@
# See https://github.com/kivy/kivy/blob/master/.ci/osx_versions.sh
# Do not use cache if versions are different
export ARIAL2=1.35.0
export SDL2=2.0.12
export SDL2_IMAGE=2.0.5
export SDL2_MIXER=2.0.4
export SDL2_TTF=2.0.15
export GSTREAMER=1.16.2
export PLATYPUS=5.3

@ -0,0 +1,91 @@
#!/bin/python3
import os
import shutil
import subprocess
import sys
from os import environ as env
binary_filename = os.path.abspath(sys.argv[1])
master_repository_directory = os.path.abspath(sys.argv[2])
data_repository = sys.argv[3]
data_repository_directory = os.path.abspath(data_repository)
demo_name = sys.argv[4]
directory = f"demo_{demo_name}"
filename = os.path.basename(binary_filename)
os.chdir(master_repository_directory)
# Include commit subject and hash to the new commit
commit_hash = (
subprocess.check_output(["git", "rev-parse", "--verify", "--short", "HEAD"])
.decode("utf-8")
.strip()
)
commit_subject = (
subprocess.check_output(["git", "log", "-1", "--pretty=format:%s"])
.decode("utf-8")
.strip()
)
is_tag = env["GITHUB_EVENT_NAME"] == "push" and env["GITHUB_REF"].startswith(
"refs/tags"
)
is_pr = env["GITHUB_REF"].startswith("refs/pull")
filename_split = filename.split("-")
if is_tag:
new_commit_message = (
f'Add binary for {filename_split[1]} {commit_hash}: "{commit_subject}"'
)
elif is_pr:
# Pull Request - prN (pr1)
pr_number = env["GITHUB_REF"].split("/")[2]
filename = "-".join(
[*filename_split[:2], f"pr{pr_number}", *filename_split[2:]]
)
directory = os.path.join(directory, "prs")
new_commit_message = (
f'Add binary for #{pr_number} {commit_hash}: "{commit_subject}"'
)
else:
# Latest commit - nightly
filename = "-".join([*filename_split[:2], "nightly", *filename_split[2:]])
new_commit_message = f'Add binary for {commit_hash}: "{commit_subject}"'
# Prepare for pushing
os.chdir(data_repository_directory)
os.makedirs(directory, exist_ok=True)
# Ensure that there is no changes
subprocess.check_call(["git", "pull", "origin", data_repository, "--ff-only"])
# Try to push several times
for i in range(3):
shutil.copy(binary_filename, os.path.join(directory, filename))
subprocess.check_call(["git", "add", os.path.join(directory, filename)])
subprocess.check_call(["git", "commit", "-m", new_commit_message])
try:
subprocess.check_call(["git", "push", "origin", data_repository])
except subprocess.CalledProcessError: # There is changes in repository
# Undo local changes
subprocess.check_call(
["git", "reset", f"origin/{data_repository}", "--hard"]
)
# Pull new changes
subprocess.check_call(
["git", "pull", "origin", data_repository, "--force", "--ff-only"]
)
else:
break # Exit loop if there is no errors
else:
raise Exception("Cannot push binary")
new_commit_hash = (
subprocess.check_output(["git", "rev-parse", "--verify", "--short", "HEAD"])
.decode("utf-8")
.strip()
)
print(
f"Binary file: {env['GITHUB_SERVER_URL']}/{env['GITHUB_REPOSITORY']}/blob/"
f"{new_commit_hash}/{directory}/{filename}"
)

@ -0,0 +1,29 @@
# See https://github.com/kivy/kivy/blob/master/.github/workflows/test_ubuntu_python.yml
# Environment variables
echo "::set-env name=DISPLAY:::99.0"
# System dependencies
sudo apt-get update
sudo apt-get -y install \
libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-mixer-dev \
libgstreamer1.0-dev gstreamer1.0-alsa gstreamer1.0-plugins-base \
libsmpeg-dev libswscale-dev libavformat-dev libavcodec-dev libjpeg-dev libtiff5-dev libx11-dev libmtdev-dev \
build-essential libgl1-mesa-dev libgles2-mesa-dev \
xvfb pulseaudio xsel
# Pip dependencies
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade \
cython \
pytest pytest-cov pytest_asyncio pytest-timeout coveralls \
pillow docutils pygments pyinstaller \
sphinx sphinxcontrib-blockdiag sphinxcontrib-seqdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag
python -m pip install --upgrade kivy==$KIVY_VERSION
# Start X-Server
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background \
--exec /usr/bin/Xvfb -- :99 -screen 0 1280x720x24 -ac +extension GLX

@ -0,0 +1,14 @@
# See https://github.com/kivy/kivy/blob/master/.github/workflows/test_windows_python.yml
# Environment variables
echo "::set-env name=GST_REGISTRY::~/registry.bin"
echo "::set-env name=KIVY_GL_BACKEND::angle_sdl2"
# Pip dependencies
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade `
cython `
pytest pytest-cov pytest_asyncio pytest-timeout coveralls `
pillow https://github.com/pyinstaller/pyinstaller/archive/develop.zip `
pypiwin32 kivy_deps.sdl2 kivy_deps.glew kivy_deps.angle kivy_deps.gstreamer
python -m pip install --upgrade kivy==$Env:KIVY_VERSION

@ -0,0 +1,60 @@
name: Build demos
on:
push:
branches-ignore:
- data
- gh-pages
tags:
- '**'
pull_request:
branches-ignore:
- data
- gh-pages
jobs:
# Build job. Builds every demo app for Android with Buildozer
build-android:
name: Build Android [${{ matrix.demo-name }}]
strategy:
fail-fast: false
matrix:
demo-name: [kitchen_sink]
runs-on: ubuntu-latest
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
with:
path: master
- name: Build with Buildozer
uses: ArtemSBulgakov/buildozer-action@v1
id: buildozer
with:
repository_root: master
workdir: demos/${{ matrix.demo-name }}
- name: Checkout data branch
uses: actions/checkout@v2
with:
path: data
ref: data # Branch name
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.7
architecture: x64
- name: Push binary to data branch
run: |
# Use personal token to push (when using GITHUB_TOKEN, it will not allow pushes from PR)
cd data && \
git config user.name "KivyMD Bot" && \
git config user.email 69076719+KivyMD-Bot@users.noreply.github.com && \
git remote set-url origin https://KivyMD-Bot:${{ secrets.GH_PAT }}@github.com/${{ github.repository }} && \
cd ..
python master/.ci/move_binary.py "${{ steps.buildozer.outputs.filename }}" master data ${{ matrix.demo-name }}

@ -0,0 +1,81 @@
name: Build
on:
push:
branches-ignore:
- data
- gh-pages
tags:
- '**'
pull_request:
branches-ignore:
- data
- gh-pages
jobs:
# Build job. Builds source distribution (sdist) and binary wheels distribution (bdist_wheel)
build:
name: Build ${{ matrix.dist }} [${{ matrix.python-version }} | ${{ matrix.os }} ${{ matrix.architecture }}]
strategy:
fail-fast: false
matrix:
# os: [ubuntu-latest, macos-latest, windows-latest] # Build wheels on different systems
# python-version: [3.6, 3.7]
# architecture: [x64]
# dist: [bdist_wheel]
include:
- os: ubuntu-latest # Modify one element to build source distribution
python-version: 3.7
architecture: x64
dist: sdist bdist_wheel
runs-on: ${{ matrix.os }}
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- name: Build
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools wheel
python setup.py ${{ matrix.dist }}
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: dist
path: dist
# Deploy job. Uploads distribution to PyPI (only on tags)
deploy:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download artifacts
uses: actions/download-artifact@v2
with:
name: dist
path: dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@v1.2.2
with:
user: __token__
password: ${{ secrets.PYPI_TOKEN }}
packages_dir: dist/

@ -0,0 +1,46 @@
name: Lint
on:
push:
branches-ignore:
- data
- gh-pages
tags:
- '**'
pull_request:
branches-ignore:
- data
- gh-pages
jobs:
# Lint job. Runs pre-commit, fails if there are changed files
lint:
name: Check pre-commit [${{ matrix.python-version }} | ${{ matrix.os }} ${{ matrix.architecture }}]
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]
python-version: [3.7]
architecture: [x64]
runs-on: ${{ matrix.os }}
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools wheel
python -m pip install --upgrade pre-commit
- name: Check pre-commit
run: pre-commit run --all-files

@ -0,0 +1,66 @@
name: Release
on:
push:
branches-ignore:
- data
- gh-pages
tags:
- '**'
pull_request:
branches-ignore:
- data
- gh-pages
workflow_dispatch:
inputs:
version:
description: New version in format n.n.n (1.111.11)
required: true
jobs:
# Release job. Runs make_release.py tool. Pushes changes only on dispatch_event
release:
name: Release
runs-on: ubuntu-latest
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: ${{ github.event_name != 'workflow_dispatch' }} # Allow using PAT when making release
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
python-version: 3.7
architecture: x64
- name: Set up environment
run: |
git config user.name "KivyMD Bot"
git config user.email 69076719+KivyMD-Bot@users.noreply.github.com
pip install -e .
pip install pre-commit
- name: Release
if: github.event_name == 'workflow_dispatch'
run: |
# Use personal token to push (when using GITHUB_TOKEN, it will not run workflows)
git remote set-url origin https://KivyMD-Bot:${{ secrets.GH_PAT }}@github.com/${{ github.repository }}
python kivymd/tools/release/make_release.py release "${{ github.event.inputs.version }}" --yes --push
git diff origin/master...
- name: Release preparation
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.event_name != 'workflow_dispatch'
run: |
python kivymd/tools/release/make_release.py prepare --yes --push
git diff origin/master...
- name: Release test
if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master' && github.event_name != 'workflow_dispatch')
run: |
python kivymd/tools/release/make_release.py test --yes
git diff origin/master...

@ -0,0 +1,89 @@
name: Test
on:
push:
branches-ignore:
- data
- gh-pages
tags:
- '**'
pull_request:
branches-ignore:
- data
- gh-pages
jobs:
# Test job. Runs pytest on Ubuntu, MacOS and Windows, uploads coverage report
test:
name: Test [${{ matrix.python-version }} | Kivy ${{ matrix.kivy-version }} | ${{ matrix.os }} ${{ matrix.architecture }}]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.7]
architecture: [x64]
kivy-version: [1.11.1]
include:
- os: windows-latest
python-version: 3.7
architecture: x86
kivy-version: 1.11.1
runs-on: ${{ matrix.os }}
env:
PYTHONUNBUFFERED: 1
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- name: Cache MacOS deps
uses: actions/cache@v2
if: startswith(matrix.os, 'macos')
with:
path: macos-cache
key: ${{ runner.OS }}-deps-${{ hashFiles('.ci/macos_versions.sh') }}
- name: Cache MacOS gst-devel deps
uses: actions/cache@v2
if: startswith(matrix.os, 'macos')
with:
path: macos-cache-gst-devel
key: gst-devel-${{ runner.OS }}-deps-gst-devel-${{ hashFiles('.ci/macos_versions.sh') }}
- name: Install dependencies for Ubuntu
if: startswith(matrix.os, 'ubuntu')
env:
KIVY_VERSION: ${{ matrix.kivy-version }}
run: .ci/ubuntu_dependencies.sh
- name: Install dependencies for MacOS
if: startswith(matrix.os, 'macos')
env:
KIVY_VERSION: ${{ matrix.kivy-version }}
run: .ci/macos_dependencies.sh
- name: Install dependencies for Windows
if: startswith(matrix.os, 'windows')
env:
KIVY_VERSION: ${{ matrix.kivy-version }}
run: .ci\windows_dependencies.ps1
- name: Install KivyMD
run: python -m pip install -e .
- name: Test
run: python -m pytest kivymd/tests --timeout=300 --cov=kivymd --cov-report=term
# Only from Ubuntu
- name: Upload coverage report
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'kivymd/KivyMD' && startswith(matrix.os, 'ubuntu')
continue-on-error: true
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: python -m coveralls

@ -0,0 +1,71 @@
# Directories and files that cannot be commited to git
# Byte-compiled
__pycache__
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
lib
lib64
parts
sdist
var
wheels
pip-wheel-metadata
share/python-wheels
develop-eggs
eggs
.eggs
*.egg-info
*.egg
MANIFEST
.installed.cfg
downloads
docs/_build
build
dist
bin
.buildozer
# Logs
*.log
pip-log.txt
pip-delete-this-directory.txt
# Editors
.vscode
.ipynb_checkpoints
*.swp
# PyCharm
.idea/*
!/.idea/*.iml
!/.idea/modules.xml
!/.idea/vcs.xml
!/.idea/runConfigurations
# Environments
venv
.venv
env
.env
.python-version
# Temp / Cache
cache
.cache
temp
.temp
.pytest_cache
.coverage
docs/sources/api
demos/kitchen_sink/assets/*crop.*
demos/kitchen_sink/assets/sasha-round.png
kivymd/tools/release/*.zip
kivymd/tools/release/temp
kivymd/_version.py

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/demos/kitchen_sink" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="kivy_venv" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PackageRequirementsSettings">
<option name="requirementsPath" value="" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="pytest" />
</component>
</module>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/KivyMD.iml" filepath="$PROJECT_DIR$/.idea/KivyMD.iml" />
</modules>
</component>
</project>

@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo: kitchen_sink" type="PythonConfigurationType" factoryName="Python">
<module name="KivyMD" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/demos/kitchen_sink" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/demos/kitchen_sink/main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo: kitchen_sink - PyInstaller build" type="PythonConfigurationType" factoryName="Python">
<module name="KivyMD" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/demos/kitchen_sink" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="PyInstaller.__main__" />
<option name="PARAMETERS" value="$ProjectFileDir$/demos/kitchen_sink/pyinstaller.spec" />
<option name="SHOW_COMMAND_LINE" value="true" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="true" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test kivymd/tests" type="tests" factoryName="py.test">
<module name="KivyMD" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/kivymd/tests" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_keywords" value="&quot;&quot;" />
<option name="_new_parameters" value="&quot;--cov\u003dkivymd --cov-report\u003dterm&quot;" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;kivymd/tests&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
</component>

@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Tool: update_icons" type="PythonConfigurationType" factoryName="Python">
<module name="KivyMD" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/kivymd/tools/release" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/kivymd/tools/release/update_icons.py" />
<option name="PARAMETERS" value="--commit" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

@ -0,0 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="pre-commit all" type="PythonConfigurationType" factoryName="Python">
<module name="KivyMD" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="pre_commit.__main__" />
<option name="PARAMETERS" value="run --all-files" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="true" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CommitMessageInspectionProfile">
<profile version="1.0">
<inspection_tool class="BodyLimit" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="RIGHT_MARGIN" value="50" />
</inspection_tool>
</profile>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,24 @@
# Pre-commit hooks.
# python3 -m pip install pre-commit
# pre-commit install
repos:
# Format Python
- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black
# Sort imports
- repo: https://github.com/timothycrosley/isort
rev: 4.3.21
hooks:
- id: isort
additional_dependencies: ["toml"]
# Lint Python
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.3
hooks:
- id: flake8

@ -0,0 +1,22 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/sources/conf.py
# Optionally build your docs in additional formats such as PDF and ePub
formats: all
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
install:
- method: pip
path: .
extra_requirements:
- docs

@ -0,0 +1,35 @@
MIT License
Copyright (c) 2015 Andrés Rodríguez and other contributors - KivyMD library up to version 0.1.2
Copyright (c) 2020 KivyMD Team and other contributors - KivyMD library version 0.1.3 and higher
Other libraries used in the project:
Copyright (c) 2010-2020 Kivy Team and other contributors
Copyright (c) 2013 Brian Knapp - Androidoast library
Copyright (c) 2014 LogicalDash - stiffscroll library
Copyright (c) 2015 Davide Depau - circularTimePicker, circleLayout libraries
Copyright (c) 2015 Kivy Garden - tabs module
Copyright (c) 2020 Nattōsai Mitō - asynckivy module
Copyright (c) 2020 tshirtman - magic_behavior module
Copyright (c) 2020 shashi278 - taptargetview module
Copyright (c) 2020 Benedikt Zwölfer - fitimage module
Hoverable Behaviour (changing when the mouse is on the widget by O. Poyen, License: LGPL) - hover_behavior module
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,238 @@
# KivyMD [v0.104.1](https://kivymd.readthedocs.io/en/latest/changelog/index.html)
<img align="left" width="256" src="https://github.com/kivymd/KivyMD/raw/master/kivymd/images/kivy-logo-white-512.png"/>
KivyMD is a collection of Material Design compliant widgets for use with [Kivy](http://kivy.org), a framework for cross-platform, touch-enabled graphical applications.
The project's goal is to approximate Google's [Material Design spec](https://material.io/design/introduction/) as close as possible without sacrificing ease of use or application performance.
This library is a fork of the [KivyMD project](https://gitlab.com/kivymd/KivyMD) the author of which stopped supporting this project three years ago. We found the strength and brought this project to a new level.
Currently we're in **beta** status, so things are changing all the time and we cannot promise any kind of API stability. However it is safe to vendor now and make use of what's currently available.
Join the project! Just fork the project, branch out and submit a pull request when your patch is ready. If any changes are necessary, we'll guide you through the steps that need to be done via PR comments or access to your for may be requested to outright submit them.
If you wish to become a project developer (permission to create branches on the project without forking for easier collaboration), have at least one PR approved and ask for it. If you contribute regularly to the project the role may be offered to you without asking too.
[![PyPI version](https://img.shields.io/pypi/v/kivymd.svg)](https://pypi.org/project/kivymd)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/kivymd.svg)](#Installation)
[![Downloads](https://pepy.tech/badge/kivymd)](https://pepy.tech/project/kivymd)
[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Discord](https://img.shields.io/discord/566880874789076992?logo=discord)](https://discord.gg/wu3qBST)
[![Twitter](https://img.shields.io/twitter/follow/KivyMD?label=follow&logo=twitter&style=flat&color=brightgreen)](https://twitter.com/KivyMD)
[![YouTube](https://img.shields.io/static/v1?label=subscribe&logo=youtube&logoColor=ff0000&color=brightgreen&message=1k)](https://www.youtube.com/c/KivyMD)
[![Habr](https://img.shields.io/static/v1?label=habr&message=ru&logo=habr&color=brightgreen)](https://habr.com/ru/users/kivymd/posts)
[![StackOverflow](https://img.shields.io/stackexchange/stackoverflow/t/%5Bkivymd%5D?color=brightgreen&label=stackoverflow&logo=stackoverflow)](https://stackoverflow.com/tags/kivymd)
[![Bountysource](https://img.shields.io/bountysource/team/kivymd/activity?label=bountysource)](https://www.bountysource.com/teams/kivymd/issues)
[![Open Collective](https://img.shields.io/opencollective/all/kivymd?label=financial%20contributors&logo=open-collective)](https://opencollective.com/KivyMD)
[![Coverage status](https://coveralls.io/repos/github/kivymd/KivyMD/badge.svg)](https://coveralls.io/github/kivymd/KivyMD)
[![Build workflow](https://github.com/kivymd/KivyMD/workflows/Build/badge.svg?branch=master)](https://github.com/kivymd/KivyMD/actions?query=workflow%3ABuild)
[![Test workflow](https://github.com/kivymd/KivyMD/workflows/Test/badge.svg?branch=master)](https://github.com/kivymd/KivyMD/actions?query=workflow%3ATest)
[![Build demos workflow](https://github.com/kivymd/KivyMD/workflows/Build%20demos/badge.svg?branch=master)](https://github.com/kivymd/KivyMD/actions?query=workflow%3A"Build+demos")
[![Documentation status](https://readthedocs.org/projects/kivymd/badge/?version=latest)](https://kivymd.readthedocs.io)
## Documentation
See documentation at https://kivymd.readthedocs.io
Wiki with examples of using KivyMD widgets: https://github.com/kivymd/KivyMD/wiki
### Demos
<p align="center">
<a href="https://www.youtube.com/watch?v=qU6C_Icp6TM">
<img width="400" src="https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/prevideo-run-in-desktop.png" title='Click to watch "How to run the KivyMD demo on desktop?" on YouTube'>
</a>
</p>
[Kitchen sink](https://github.com/kivymd/KivyMD/tree/master/demos/kitchen_sink) app demonstrates every KivyMD widget. You can see how to use widget in code of app. You can download apk for your smartphone (Android 6.0 and higher): [data branch](https://github.com/kivymd/KivyMD/tree/data/demo_kitchen_sink).
### Tutorials on YouTube
<p align="center">
<a href="https://www.youtube.com/watch?v=kRWtSkIYPFI&list=PLy5hjmUzdc0nMkzhphsqgPCX62NFhkell&index=1">
<img width="400" src="https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/tutorial.png" title="Click to watch KivyMD Tutorials on YouTube">
</a>
</p>
[Tutorials](https://www.youtube.com/watch?v=kRWtSkIYPFI&list=PLy5hjmUzdc0nMkzhphsqgPCX62NFhkell&index=1) by [Erik Sandberg](https://github.com/Dirk-Sandberg) show you how to create application with KivyMD and use its widgets.
## Support
If you need assistance or you have a question, you can ask for help on our mailing list:
- **Discord server:** https://discord.gg/wu3qBST (English #support, Russian #ru-support)
- _StackOverflow tag:_ [kivymd](https://stackoverflow.com/tags/kivymd)
- _Email:_ kivydevelopment@gmail.com
## Installation
### Dependencies:
- [Kivy](https://github.com/kivy/kivy) >= 1.10.1 ([Installation](https://kivy.org/doc/stable/gettingstarted/installation.html))
- [Python 3.6+](https://www.python.org/) _(Python 2 not supported)_
### How to install
```bash
pip install kivymd==0.104.1
```
Command above will install latest release version of KivyMD from [PyPI](https://pypi.org/project/kivymd).
If you want to install development version from [master](https://github.com/kivymd/KivyMD/tree/master/)
branch, you should specify link to zip archive:
```bash
pip install https://github.com/kivymd/KivyMD/archive/master.zip
```
**_Tip_**: Replace `master.zip` with `<commit hash>.zip` (eg `51b8ef0.zip`) to
download KivyMD from specific commit.
Also you can install manually from sources. Just clone the project and run pip:
```bash
git clone https://github.com/kivymd/KivyMD.git --depth 1
cd KivyMD
pip install .
```
**_Speed Tip_**: If you don't need full commit history (about 320 MiB), you can
use a shallow clone (`git clone https://github.com/kivymd/KivyMD.git --depth 1`)
to save time. If you need full commit history, then remove `--depth 1`.
### How to use with [Buildozer](https://github.com/kivy/buildozer)
```ini
requirements = kivy==1.11.1, kivymd==0.104.1
```
This will download latest release version of KivyMD from [PyPI](https://pypi.org/project/kivymd).
If you want to use development version from [master](https://github.com/kivymd/KivyMD/tree/master/)
branch, you should specify link to zip archive:
```ini
requirements = kivy==1.11.1, https://github.com/kivymd/KivyMD/archive/master.zip
```
Do not forget to run `buildozer android clean` or remove `.buildozer` directory
before building if version was updated (Buildozer doesn't update already
downloaded packages).
#### On Linux
Use Buildozer [directly](https://github.com/kivy/buildozer#installing-buildozer-with-target-python-3-default)
or via [Docker](https://github.com/kivy/buildozer/blob/master/Dockerfile).
#### On Windows 10
Install [Ubuntu WSL](https://ubuntu.com/wsl) and follow [Linux steps](#On-Linux).
#### On Windows without WSL
Install VirtualBox and follow steps from [here](https://github.com/kivymd/KivyMD/blob/9b969f39d8bb03c73de105b82e66de3820020eb9/README.md#building-with-vm).
#### Build automatically via GitHub Actions
Use [ArtemSBulgakov/buildozer-action@v1](https://github.com/ArtemSBulgakov/buildozer-action)
to build your packages automatically on push or pull request.
See [full workflow example](https://github.com/ArtemSBulgakov/buildozer-action#full-workflow).
## Settings
#### [Syntax highlighting and auto-completion for Kivy/KivyMD .kv files in PyCharm/Intellij IDEA](https://github.com/noembryo/KV4Jetbrains)
## API Breaking changes
- [Changed MDExpansionPanel panel creation](https://kivymd.readthedocs.io/en/latest/components/expansion-panel/index.html)
- [Changed the use of the MDDropdownMenu](https://kivymd.readthedocs.io/en/latest/components/menu/index.html)
- [Changed the use of the MDDropDownItem](https://kivymd.readthedocs.io/en/latest/components/dropdown-item/index.html)
- [Changed the use of the MDDialog](https://kivymd.readthedocs.io/en/latest/components/dialog/index.html)
## Video preview
<p align="center">
<a href="https://www.youtube.com/watch?v=HCa8zij69kY">
<img src="https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/prevideo.png" title='Click to watch video on YouTube'>
</a>
</p>
## Image preview
<p align="center">
<img src="https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/previous.png">
</p>
## Contributing
We always welcome your [Bug reports](https://github.com/kivymd/KivyMD/issues/new?template=bug_report.md),
[Feature requests](https://github.com/kivymd/KivyMD/issues/new?template=feature_request.md)
and [Pull requests](https://github.com/kivymd/KivyMD/pulls)!
Check out [CONTRIBUTING.md](https://github.com/kivymd/.github/blob/master/.github/CONTRIBUTING.md)
and feel free to improve KivyMD.
### Setup environment
We recommend you to use PyCharm to work with KivyMD code. Install
[Kivy](https://kivy.org/doc/stable/gettingstarted/installation.html) and
development dependencies to your virtual environment:
```bash
pip install -e .[dev,docs]
pre-commit install
```
Format all files and run tests:
```bash
pre-commit run --all-files
pytest kivymd/tests --timeout=300 --cov=kivymd --cov-report=term
```
pre-commit will format modified files with Black and sort imports with isort.
## Sister projects
- [Creator Kivy Project](https://github.com/HeaTTheatR/CreatorKivyProject) - Wizard for creating a new project for applications written using the Kivy framework
## License
KivyMD is released under the terms of the [MIT License](https://github.com/kivymd/KivyMD/blob/master/LICENSE), same as [Kivy](https://github.com/kivy/kivy/blob/master/LICENSE).
[Roboto font](https://fonts.google.com/specimen/Roboto) is licensed and distributed under the terms of the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).
[Iconic font](https://github.com/Templarian/MaterialDesign-Webfont) by the [Material Design Icons](https://materialdesignicons.com/) community covered by [SIL Open Font License 1.1](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web)
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](.github/CONTRIBUTING.md)].
<a href="https://github.com/kivymd/KivyMD/graphs/contributors"><img src="https://opencollective.com/KivyMD/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/KivyMD/contribute)]
#### Individuals
<a href="https://opencollective.com/KivyMD"><img src="https://opencollective.com/KivyMD/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/KivyMD/contribute)]
<a href="https://opencollective.com/KivyMD/organization/0/website"><img src="https://opencollective.com/KivyMD/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/1/website"><img src="https://opencollective.com/KivyMD/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/2/website"><img src="https://opencollective.com/KivyMD/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/3/website"><img src="https://opencollective.com/KivyMD/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/4/website"><img src="https://opencollective.com/KivyMD/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/5/website"><img src="https://opencollective.com/KivyMD/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/6/website"><img src="https://opencollective.com/KivyMD/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/7/website"><img src="https://opencollective.com/KivyMD/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/8/website"><img src="https://opencollective.com/KivyMD/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/KivyMD/organization/9/website"><img src="https://opencollective.com/KivyMD/organization/9/avatar.svg"></a>

@ -0,0 +1,34 @@
[b]The MIT License (MIT)[/b]
[i]Copyright (c) 2015 [color={COLOR}]Andrés Rodríguez[/color] and [color={COLOR}]KivyMD contributors[/color] - KivyMD library up to version 0.1.2
Copyright (c) 2019 [color={COLOR}]Ivanov Yuri[/color] and [color={COLOR}]KivyMD contributors[/color] - KivyMD library version 0.1.3 and higher[/i]
[b]Other libraries used in the project:[/b]
[i]Copyright (c) 2010-2019 [color={COLOR}]Kivy Team[/color] and other contributors
Copyright (c) 2013 [color={COLOR}]Brian Knapp[/color] - [b]Androidoast[/b] library
Copyright (c) 2014 [color={COLOR}]LogicalDash[/color] - [b]stiffscroll[/b] library
Copyright (c) 2015 [color={COLOR}]Davide Depau[/color] - [b]circularTimePicker, circleLayout[/b] libraries
Copyright (c) 2015 [color={COLOR}]Kivy Garden[/color] - [b]tabs[/b] module
Copyright (c) 2019 [color={COLOR}]Nattōsai Mitō[/color] - [b]asynckivy[/b] module
Copyright (c) 2019 [color={COLOR}]tshirtman[/color] - [b]magic_behavior[/b] module
Copyright (c) 2019 [color={COLOR}]Benedikt Zwölfer[/color] - [b]fitimage[/b] module
Hoverable Behaviour (changing when the mouse is on the widget by [color={COLOR}]O. Poyen[/color] , License: LGPL) - [b]hover_behavior[/b] module[/i]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
[b]THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.[/b]

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

@ -0,0 +1,267 @@
![backdrop.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/backdrop.gif)
## Example of using MDBottomAppBar:
```python
from kivy.lang import Builder
from kivy.properties import StringProperty, BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivymd.app import MDApp
from kivymd.theming import ThemableBehavior
# Your layouts.
Builder.load_string(
"""
#:import NoTransition kivy.uix.screenmanager.NoTransition
#:import Window kivy.core.window.Window
#:import IconLeftWidget kivymd.uix.list.IconLeftWidget
<ItemBackdropFrontLayer@TwoLineAvatarListItem>
icon: "android"
IconLeftWidget:
icon: root.icon
<ItemBackdropBackLayer>
size_hint_y: None
height: self.minimum_height
spacing: "10dp"
canvas:
Color:
rgba:
root.theme_cls.primary_dark if root.selected_item \
else root.theme_cls.primary_color
RoundedRectangle:
pos: self.pos
size: self.size
MDIconButton:
icon: root.icon
theme_text_color: "Custom"
text_color: 1, 1, 1, .5 if not root.selected_item else 1, 1, 1, 1
MDLabel:
text: root.text
color: 1, 1, 1, .5 if not root.selected_item else 1, 1, 1, 1
<ItemBackdropBackLayerOfSecondScreen@BoxLayout>
size_hint_y: None
height: "40dp"
spacing: "25dp"
text: ""
MDCheckbox:
size_hint: None, None
size: "30dp", "30dp"
active: False or self.active
pos_hint: {"center_y": .5}
selected_color: 1, 1, 1, 1
MDLabel:
text: root.text
color: 1, 1, 1, .7
<ItemRoundBackdropBackLayerOfSecondScreen@BoxLayout>
size_hint_y: None
height: "40dp"
spacing: "25dp"
text: ""
MDCheckbox:
group: "size"
size_hint: None, None
size: "30dp", "30dp"
pos_hint: {"center_y": .5}
selected_color: 1, 1, 1, 1
MDLabel:
text: root.text
color: 1, 1, 1, .7
<MyBackdropFrontLayer@ScrollView>
backdrop: None
backlayer: None
GridLayout:
size_hint_y: None
height: self.minimum_height
cols: 1
padding: "5dp"
ItemBackdropFrontLayer:
text: "Press item"
secondary_text: "to Shop Electronics"
icon: "monitor-star"
on_press:
root.backlayer.current = "second screen"
root.backdrop.open()
ItemBackdropFrontLayer:
text: "Press item"
secondary_text: "to Back"
icon: "arrange-send-backward"
on_press:
root.backlayer.current = "one screen"
root.backdrop.open()
ItemBackdropFrontLayer:
text: "Lower the front layer"
secondary_text: " by 50 %"
icon: "transfer-down"
on_press:
root.backdrop.open(-Window.height / 2)
<MyBackdropBackLayer@ScreenManager>
transition: NoTransition()
Screen:
name: "one screen"
ScrollView
GridLayout:
size_hint_y: None
height: self.minimum_height
cols: 1
padding: "5dp"
ItemBackdropBackLayer:
icon: 'theater'
text: "TV & Home Theaters"
ItemBackdropBackLayer:
icon: 'desktop-mac'
text: "Computers"
ItemBackdropBackLayer:
icon: 'camera-plus-outline'
text: "Camera and Camcorders"
ItemBackdropBackLayer:
icon: 'speaker'
text: "Speakers"
ItemBackdropBackLayer:
icon: 'cellphone-iphone'
text: "Mobile Phones"
ItemBackdropBackLayer:
icon: 'movie-outline'
text: "Movies"
ItemBackdropBackLayer:
icon: 'gamepad-variant-outline'
text: "Games"
ItemBackdropBackLayer:
icon: 'music-circle-outline'
text: "Music"
Screen:
name: "second screen"
ScrollView
GridLayout:
size_hint_y: None
height: self.minimum_height
cols: 1
padding: "15dp"
spacing: "10dp"
MDLabel:
text: "Types of TVs Home Theater Product"
color: 1, 1, 1, 1
Widget:
size_hint_y: None
height: "10dp"
ItemBackdropBackLayerOfSecondScreen:
text: "Smart TV"
ItemBackdropBackLayerOfSecondScreen:
text: "4K Ultra HD TVs"
ItemBackdropBackLayerOfSecondScreen:
text: "Curved TVs"
ItemBackdropBackLayerOfSecondScreen:
text: "OLED TVs"
ItemBackdropBackLayerOfSecondScreen:
text: "LED TVs"
ItemBackdropBackLayerOfSecondScreen:
text: "Home Theater Systems"
MDSeparator:
Widget:
size_hint_y: None
height: "15dp"
MDLabel:
text: "Types of TVs Home Theater Product"
color: 1, 1, 1, 1
ItemRoundBackdropBackLayerOfSecondScreen:
text: "TVs up to 32\\""
ItemRoundBackdropBackLayerOfSecondScreen:
text: "TVs 39\\"-50\\""
ItemRoundBackdropBackLayerOfSecondScreen:
text: "TVs 55\\" or larger"
"""
)
# Usage example of MDBackdrop.
Builder.load_string(
"""
<ExampleBackdrop>
MDBackdrop:
id: backdrop
on_open: print("on_open")
on_close: print("on_close")
left_action_items: [['menu', lambda x: self.open()]]
title: "Example Backdrop"
header_text: "Menu:"
MDBackdropBackLayer:
MyBackdropBackLayer:
id: backlayer
MDBackdropFrontLayer:
MyBackdropFrontLayer:
backdrop: backdrop
backlayer: backlayer
"""
)
class ExampleBackdrop(Screen):
pass
class ItemBackdropBackLayer(ThemableBehavior, BoxLayout):
icon = StringProperty("android")
text = StringProperty()
selected_item = BooleanProperty(False)
def on_touch_down(self, touch):
if self.collide_point(touch.x, touch.y):
for item in self.parent.children:
if item.selected_item:
item.selected_item = False
self.selected_item = True
return super().on_touch_down(touch)
class Test(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.primary_palette = "DeepPurple"
def build(self):
return ExampleBackdrop()
Test().run()
```

@ -0,0 +1,141 @@
![banner.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/banner.gif)
## Example of using MDBottomAppBar:
```python
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.app import MDApp
Builder.load_string("""
<ExampleBanner@Screen>
MDBanner:
id: banner
over_widget: scroll
MDToolbar:
id: toolbar
title: "Example Banners"
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items: [['dots-vertical', lambda x: None]]
pos_hint: {'top': 1}
ScrollView:
id: scroll
size_hint_y: None
height: Window.height - toolbar.height
GridLayout:
id: box
size_hint_y: None
height: self.minimum_height
cols: 1
padding: "10dp"
spacing: "10dp"
OneLineListItem:
text: "ThreeLineBanner"
on_release:
banner.type = "three-line"
banner.text = \
[\
"Three line string text example with two actions.", \
"This is the second line of the banner message,", \
"and this is the third line of the banner message.",
]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "TwoLineBanner"
on_release:
banner.type = "two-line"
banner.text = \
[\
"One line string text example with two actions.", \
"This is the second line of the banner message.", \
]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "OneLineBanner"
on_release:
banner.type = "one-line"
banner.text = ["One line string text example with two actions."]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "ThreeLineIconBanner"
on_release:
banner.type = "three-line-icon"
banner.text = \
[\
"Three line string text example with two actions.", \
"This is the second line of the banner message,", \
"and this is the third line of the banner message.",
]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "TwoLineIconBanner"
on_release:
banner.type = "two-line-icon"
banner.text = \
[\
"One line string text example with two actions.", \
"This is the second line of the banner message.", \
]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "OneLineIconBanner"
on_release:
banner.type = "one-line-icon"
banner.text = ["One line string text example with two actions."]
banner.left_action = ["CANCEL", lambda x: None]
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
OneLineListItem:
text: "Banner without actions"
on_release:
banner.type = "one-line-icon"
banner.text = ["One line string text example without actions."]
banner.left_action = []
banner.right_action = []
banner.show()
OneLineListItem:
text: "Banner with one actions"
on_release:
banner.type = "one-line-icon"
banner.text = ["One line string text example without actions."]
banner.left_action = []
banner.right_action = ["CLOSE", lambda x: banner.hide()]
banner.show()
""")
class Test(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.primary_palette = "DeepPurple"
def build(self):
return Factory.ExampleBanner()
Test().run()
```

@ -0,0 +1,129 @@
![appbar.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/appbar.gif)
## Example of using MDBottomAppBar:
```python
from kivy.factory import Factory
from kivymd.app import MDApp
from kivy.lang import Builder
Builder.load_string(
"""
<StyleLabel@MDLabel>:
size_hint_y: None
height: self.texture_size[1]
<StyleItemCheck@BoxLayout>:
group: ""
text: ""
active: False
size_hint_y: None
height: self.minimum_height
MDCheckbox:
group: root.group
active: root.active
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {"center_y": .5}
on_active: app.callback(root.text, self.active)
StyleLabel:
text: root.text
pos_hint: {"center_y": .5}
<BottomAppBar@Screen>
name: 'bottom app bar'
BoxLayout:
spacing: dp(10)
orientation: 'vertical'
MDToolbar:
title: "Title"
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: x]]
ScrollView:
GridLayout:
size_hint_y: None
height: self.minimum_height
cols: 1
padding: "10dp"
spacing: "10dp"
MDSeparator:
StyleLabel:
text: "Notch"
StyleItemCheck:
group: 'notch'
text: "On"
active: True
StyleItemCheck:
group: 'notch'
text: "Off"
MDSeparator:
StyleLabel:
text: "Position"
StyleItemCheck:
group: 'pos'
text: "Attached - Center"
active: True
StyleItemCheck:
group: 'pos'
text: "Attached - End"
StyleItemCheck:
group: 'pos'
text: "Free - Center"
StyleItemCheck:
group: 'pos'
text: "Free - End"
MDBottomAppBar
MDToolbar:
id: toolbar
title: "Title"
icon: "git"
type: "bottom"
left_action_items: [["menu", lambda x: x]]
"""
)
class BottomAppBarTest(MDApp):
def callback(self, text, value):
if value and self.root:
if text == "Off":
self.root.ids.toolbar.remove_notch()
elif text == "On":
self.root.ids.toolbar.set_notch()
elif text == "Attached - End":
self.root.ids.toolbar.mode = "end"
elif text == "Attached - Center":
self.root.ids.toolbar.mode = "center"
elif text == "Free - End":
self.root.ids.toolbar.mode = "free-end"
elif text == "Free - Center":
self.root.ids.toolbar.mode = "free-center"
def build(self):
return Factory.BottomAppBar()
BottomAppBarTest().run()
```

@ -0,0 +1,89 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/bottom-navigation.gif)
## Example of using MDBottomNavigation:
```python
from kivy.app import App
from kivy.lang import Builder
from kivymd.theming import ThemeManager
class Test(App):
theme_cls = ThemeManager()
def build(self):
return Builder.load_string(
'''
BoxLayout:
orientation:'vertical'
MDToolbar:
id: toolbar
title: 'Test MDBottomNavigation'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: '']]
MDBottomNavigation:
id: panel
MDBottomNavigationItem:
name: 'files1'
text: 'Python'
icon: 'language-python'
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
spacing: dp(10)
pos_hint: {'center_x': .5, 'center_y': .5}
MDLabel:
font_style: 'Body1'
text: 'Toggle to set custom panel color'
halign: 'center'
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': .5}
on_active:
panel.panel_color = \
[0.2980392156862745, 0.2823529411764706, 0.32941176470588235, 1] \
if self.active else app.theme_cls.bg_dark
MDBottomNavigationItem:
name: 'files2'
text: 'C++'
icon: 'language-cpp'
MDLabel:
font_style: 'Body1'
text: 'I programming of C++'
halign: 'center'
MDBottomNavigationItem:
name: 'files3'
text: 'JS'
icon: 'language-javascript'
MDLabel:
font_style: 'Body1'
text: 'Oh god JS again'
halign: 'center'
''')
if __name__ == "__main__":
Test().run()
```
Or MDBottomNavigation with custom of panel color:
![bottom-navigation-with-custom-color-panel.png](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/bottom-navigation-with-custom-color-panel.png)
```
MDBottomNavigation:
panel_color:
[0.2980392156862745, 0.2823529411764706, 0.32941176470588235, 1]
```

@ -0,0 +1,306 @@
![bottomsheet.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/bottomsheet.gif)
## Example of using MDBottomSheet:
```python
from kivy.app import App
from kivy.factory import Factory
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.uix.bottomsheet import (
MDCustomBottomSheet,
MDGridBottomSheet,
MDListBottomSheet,
)
Builder.load_string(
'''
#:import Window kivy.core.window.Window
#:import get_hex_from_color kivy.utils.get_hex_from_color
<ContentForPopupScreen@BoxLayout>
id: box
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
pos_hint: {'top': 1}
BoxLayout:
size_hint_y: None
height: self.minimum_height
Widget:
MDRoundFlatButton:
text: "Free call"
on_press: app.callback_for_menu_items(self.text)
md_bg_color: 1, 1, 1, .4
text_color: app.theme_cls.bg_dark
Widget:
MDRoundFlatButton:
text: "Free message"
on_press: app.callback_for_menu_items(self.text)
md_bg_color: 1, 1, 1, .4
text_color: app.theme_cls.bg_dark
Widget:
OneLineIconListItem:
text: "Video call"
on_press: app.callback_for_menu_items(self.text)
IconLeftWidget:
icon: 'camera-front-variant'
TwoLineIconListItem:
text: "Call Viber Out"
on_press: app.callback_for_menu_items(self.text)
secondary_text:
"[color=%s]Advantageous rates for calls[/color]" \
% get_hex_from_color([0, 0, 0, .5])
IconLeftWidget:
icon: 'phone'
TwoLineIconListItem:
text: "Call over mobile network"
on_press: app.callback_for_menu_items(self.text)
secondary_text:
"[color=%s]Operator's tariffs apply[/color]" \
% get_hex_from_color([0, 0, 0, .5])
IconLeftWidget:
icon: 'remote'
<BoxContentForBottomSheetCustomScreenList>
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
pos_hint: {'top': 1}
ScrollView:
GridLayout:
id: box
size_hint_y: None
height: self.minimum_height
cols: 1
<ContentForBottomSheetCustomScreenList@TwoLineIconListItem>
text: "Call over mobile network"
on_press: app.callback_for_menu_items(self.text)
secondary_text:
"[color=%s]Operator's tariffs apply[/color]" \
% get_hex_from_color([0, 0, 0, .5])
IconLeftWidget:
icon: 'remote'
<CustomItemButton@AnchorLayout>
size_hint_y: None
height: "32dp"
anchor_x: "center"
text: ""
callback: None
MDRaisedButton:
text: root.text
on_release: root.callback()
<BottomSheet@Screen>
name: 'bottom sheet'
BoxLayout:
orientation: 'vertical'
spacing: dp(10)
MDToolbar:
title: 'Example BottomSheet'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: x]]
background_palette: 'Primary'
ScrollView:
GridLayout:
size_hint_y: None
height: self.minimum_height
spacing: "20dp"
padding: "20dp"
cols: 1
CustomItemButton:
text: "Open custom bottom sheet"
callback: lambda: app.show_example_custom_bottom_sheet("custom")
CustomItemButton:
text: "Open custom bottom sheet with list"
callback: lambda: app.show_example_custom_bottom_sheet("list")
CustomItemButton:
text: "Open list bottom sheet"
callback: lambda: app.show_example_bottom_sheet()
CustomItemButton:
text: "Open grid bottom sheet"
callback: lambda: app.show_example_grid_bottom_sheet()
Widget:
size_hint_y: None
height: "5dp"
MDLabel:
text: "MDBottomSheet corners"
halign: "center"
font_style: "H6"
MDSeparator:
CustomItemButton:
text: "Corner 'top_left'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "top_left")
CustomItemButton:
text: "Corner 'top_right'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "top_right")
CustomItemButton:
text: "Corners 'top'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "top")
CustomItemButton:
text: "Corner 'bottom_left'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "bottom_left")
CustomItemButton:
text: "Corner 'bottom_right'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "bottom_right")
CustomItemButton:
text: "Corners 'bottom'"
callback: lambda: app.show_example_custom_bottom_sheet("custom", "bottom")
Widget:
size_hint_y: None
height: "5dp"
MDLabel:
text: "MDBottomSheet without animation opening"
halign: "center"
font_style: "H6"
MDSeparator:
CustomItemButton:
text: "MDBottomSheet without animation opening"
callback: lambda: app.show_example_custom_bottom_sheet("custom", None, False)
'''
)
class BoxContentForBottomSheetCustomScreenList(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(10):
self.ids.box.add_widget(
Factory.ContentForBottomSheetCustomScreenList()
)
class Example(App):
theme_cls = ThemeManager()
def build(self):
return Factory.BottomSheet()
def callback_for_menu_items(self, *args):
toast(args[0])
def show_example_custom_bottom_sheet(
self, type, corner=None, animation=True
):
"""Show menu from the screen BottomSheet."""
if type == "custom":
custom_screen_for_bottom_sheet = Factory.ContentForPopupScreen()
elif type == "list":
custom_screen_for_bottom_sheet = (
BoxContentForBottomSheetCustomScreenList()
)
MDCustomBottomSheet(
screen=custom_screen_for_bottom_sheet,
bg_color=[0.2, 0.2, 0.2, 1],
animation=animation,
radius_from=corner,
).open()
def show_example_bottom_sheet(self):
bs_menu = MDListBottomSheet()
bs_menu.add_item(
"Here's an item with text only",
lambda x: self.callback_for_menu_items(
"Here's an item with text only"
),
)
bs_menu.add_item(
"Here's an item with an icon",
lambda x: self.callback_for_menu_items(
"Here's an item with an icon"
),
icon="clipboard-account",
)
bs_menu.add_item(
"Here's another!",
lambda x: self.callback_for_menu_items("Here's another!"),
icon="nfc",
)
bs_menu.open()
def show_example_grid_bottom_sheet(self):
bs_menu = MDGridBottomSheet()
bs_menu.add_item(
"Facebook",
lambda x: self.callback_for_menu_items("Facebook"),
icon_src="demos/kitchen_sink/assets/facebook-box.png",
)
bs_menu.add_item(
"YouTube",
lambda x: self.callback_for_menu_items("YouTube"),
icon_src="demos/kitchen_sink/assets/youtube-play.png",
)
bs_menu.add_item(
"Twitter",
lambda x: self.callback_for_menu_items("Twitter"),
icon_src="demos/kitchen_sink/assets/twitter.png",
)
bs_menu.add_item(
"Da Cloud",
lambda x: self.callback_for_menu_items("Da Cloud"),
icon_src="demos/kitchen_sink/assets/cloud-upload.png",
)
bs_menu.add_item(
"Camera",
lambda x: self.callback_for_menu_items("Camera"),
icon_src="demos/kitchen_sink/assets/camera.png",
)
bs_menu.open()
Example().run()
```

@ -0,0 +1,210 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/buttons.gif)
## Example of using MDButtons:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.theming import ThemeManager
Builder.load_string("""
<ExampleButtons@BoxLayout>:
orientation: 'vertical'
MDToolbar:
id: toolbar
title: app.title
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
elevation: 10
left_action_items: [['dots-vertical', lambda x: None]]
ScrollView:
size_hint_x: None
width: box.width
pos_hint: {'center_x': .5}
bar_width: 0
BoxLayout:
id: box
padding: dp(10)
size_hint: None, None
size: self.minimum_size
spacing: dp(10)
orientation: 'vertical'
pos_hint: {'center_x': .5}
BoxLayout:
size_hint: None, None
width: self.minimum_width
height: dp(56)
spacing: '10dp'
MDIconButton:
icon: 'sd'
MDFloatingActionButton:
icon: 'plus'
opposite_colors: True
elevation_normal: 8
MDFloatingActionButton:
icon: 'check'
opposite_colors: True
elevation_normal: 8
md_bg_color: app.theme_cls.primary_color
MDIconButton:
icon: 'sd'
theme_text_color: 'Custom'
text_color: app.theme_cls.primary_color
MDFlatButton:
text: 'MDFlatButton'
pos_hint: {'center_x': .5}
MDRaisedButton:
text: "MDRaisedButton"
elevation_normal: 2
opposite_colors: True
pos_hint: {'center_x': .5}
MDRectangleFlatButton:
text: "MDRectangleFlatButton"
pos_hint: {'center_x': .5}
MDRectangleFlatIconButton:
text: "MDRectangleFlatIconButton"
icon: "language-python"
width: dp(230)
pos_hint: {'center_x': .5}
MDRoundFlatButton:
text: "MDRoundFlatButton"
pos_hint: {'center_x': .5}
MDRoundFlatIconButton:
text: "MDRoundFlatIconButton"
icon: "language-python"
width: dp(200)
pos_hint: {'center_x': .5}
MDFillRoundFlatButton:
text: "MDFillRoundFlatButton"
pos_hint: {'center_x': .5}
MDFillRoundFlatIconButton:
text: "MDFillRoundFlatIconButton"
icon: "language-python"
pos_hint: {'center_x': .5}
MDTextButton:
text: "MDTextButton"
pos_hint: {'center_x': .5}
BoxLayout:
orientation: 'vertical'
spacing: '10dp'
size_hint: None, None
size: self.minimum_size
pos_hint: {'center_x': .5}
MDSeparator:
Label:
text: 'Button customization'
color: app.theme_cls.text_color
font_size: '20sp'
size_hint: None, None
size: self.texture_size
MDSeparator:
########################################
# CUSTOMIZATION BUTTONS
########################################
MDRaisedButton:
text: "MDRaisedButton"
elevation_normal: 2
opposite_colors: True
pos_hint: {'center_x': .5}
text_color: 1, 0, 0, 1
MDRaisedButton:
text: "MDRaisedButton"
elevation_normal: 2
opposite_colors: True
pos_hint: {'center_x': .5}
md_bg_color: 1, 0, 0, 1
MDRectangleFlatButton:
text: "MDRectangleFlatButton"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
MDRectangleFlatButton:
text: "MDRectangleFlatButton"
pos_hint: {'center_x': .5}
md_bg_color: 1, 0, 0, 1
text_color: 1, 1, 0, 1
MDRoundFlatButton:
text: "MDRoundFlatButton"
pos_hint: {'center_x': .5}
md_bg_color: 1, 0, 0, 1
MDRoundFlatButton:
text: "MDRoundFlatButton"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
MDRoundFlatButton:
text: "MDRoundFlatButton"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
md_bg_color: 1, 0, 0, 1
MDRoundFlatIconButton:
text: "MDRoundFlatIconButton"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
width: dp(210)
MDRoundFlatIconButton:
text: "MDRoundFlatIconButton"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
md_bg_color: 1, 0, 0, 1
width: dp(210)
MDFillRoundFlatIconButton:
text: "MDFillRoundFlatIconButton"
icon: "language-python"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
MDFillRoundFlatIconButton:
text: "MDFillRoundFlatIconButton"
icon: "language-python"
pos_hint: {'center_x': .5}
text_color: 1, 1, 0, 1
md_bg_color: 1, 0, 0, 1
""")
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = "Example Buttons"
main_widget = None
def build(self):
return Factory.ExampleButtons()
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,106 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/card.gif)
## Example of using a class MDCardPost:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.uix.card import MDCardPost
from kivymd.theming import ThemeManager
from kivymd.toast import toast
Builder.load_string("""
<ExampleCardPost@BoxLayout>:
orientation: 'vertical'
spacing: dp(5)
MDToolbar:
id: toolbar
title: app.title
left_action_items: [['menu', lambda x: None]]
elevation: 10
md_bg_color: app.theme_cls.primary_color
ScrollView:
id: scroll
size_hint: 1, 1
do_scroll_x: False
GridLayout:
id: grid_card
cols: 1
spacing: dp(5)
padding: dp(5)
size_hint_y: None
height: self.minimum_height
""")
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Card Post"
cards_created = False
def build(self):
self.screen = Factory.ExampleCardPost()
return self.screen
def on_start(self):
def callback_for_menu_items(text_item):
toast(text_item)
def callback(instance, value):
if value and isinstance(value, int):
toast('Set like in %d stars' % value)
elif value and isinstance(value, str):
toast('Repost with %s ' % value)
elif value and isinstance(value, list):
toast(value[1])
else:
toast('Delete post %s' % str(instance))
instance_grid_card = self.screen.ids.grid_card
buttons = ['facebook', 'vk', 'twitter']
menu_items = [
{'viewclass': 'MDMenuItem',
'text': 'Example item %d' % i,
'callback': callback_for_menu_items}
for i in range(2)
]
if not self.cards_created:
self.cards_created = True
instance_grid_card.add_widget(
MDCardPost(text_post='Card with text',
swipe=True, callback=callback))
instance_grid_card.add_widget(
MDCardPost(
right_menu=menu_items, swipe=True,
text_post='Card with a button to open the menu MDDropDown',
callback=callback))
instance_grid_card.add_widget(
MDCardPost(
likes_stars=True, callback=callback, swipe=True,
text_post='Card with asterisks for voting.'))
instance_grid_card.add_widget(
MDCardPost(
source="./assets/kitten-1049129_1280.jpg",
tile_text="Little Baby",
tile_font_style="H5",
text_post="This is my favorite cat. He's only six months "
"old. He loves milk and steals sausages :) "
"And he likes to play in the garden.",
with_image=True, swipe=True, callback=callback,
buttons=buttons))
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,155 @@
![chips.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/chips.gif)
## Example of using MDChip:
```python
from kivy.app import App
from kivy.lang import Builder
from kivymd.theming import ThemeManager
kv = """
BoxLayout:
orientation: 'vertical'
spacing: dp(10)
MDToolbar:
title: 'Example Chips'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: x]]
background_palette: 'Primary'
ScrollView:
GridLayout:
padding: dp(10)
spacing: dp(10)
cols: 1
size_hint_y: None
height: self.minimum_height
MDLabel:
text: 'Chips with color:'
MDSeparator:
StackLayout:
size_hint_y: None
height: self.minimum_height
spacing: dp(5)
MDChip:
label: 'Coffee'
color: .4470588235294118, .19607843137254902, 0, 1
icon: 'coffee'
callback: app.callback
MDChip:
label: 'Duck'
color: .9215686274509803, 0, 0, 1
icon: 'duck'
callback: app.callback
MDChip:
label: 'Earth'
color: .21176470588235294, .09803921568627451, 1, 1
icon: 'earth'
callback: app.callback
MDChip:
label: 'Face'
color: .20392156865098, .48235294117606, .43529411764705883, 1
icon: 'face'
callback: app.callback
MDChip:
label: 'Facebook'
color: .5607843137254902, .48235294164706, .435294117705883, 1
icon: 'facebook'
callback: app.callback
Widget:
size_hint_y: None
height: dp(5)
MDLabel:
text: 'Chip without icon:'
MDSeparator:
StackLayout:
size_hint_y: None
height: self.minimum_height
spacing: dp(5)
MDChip:
label: 'Without icon'
icon: ''
callback: app.callback
Widget:
size_hint_y: None
height: dp(5)
MDLabel:
text: 'Chips with check:'
MDSeparator:
StackLayout:
size_hint_y: None
height: self.minimum_height
spacing: dp(5)
MDChip:
label: 'Check'
icon: ''
check: True
callback: app.callback
MDChip:
label: 'Check with icon'
icon: 'city'
check: True
callback: app.callback
Widget:
size_hint_y: None
height: dp(5)
MDLabel:
text: 'Choose chip:'
MDSeparator:
MDChooseChip:
MDChip:
label: 'Earth'
icon: 'earth'
callback: app.callback
MDChip:
label: 'Face'
icon: 'face'
callback: app.callback
MDChip:
label: 'Facebook'
icon: 'facebook'
callback: app.callback
"""
class MyApp(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Red'
def callback(self, name_chip):
pass
def build(self):
return Builder.load_string(kv)
if __name__ == "__main__":
MyApp().run()
```

@ -0,0 +1,81 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/data-picker.gif)
## Example of using MDDatePicker:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.theming import ThemeManager
from kivymd.uix.picker import MDDatePicker
KV = """
<Pickers@Screen>
name: 'pickers'
BoxLayout:
orientation: 'vertical'
spacing: dp(20)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint_y: None
height: self.minimum_height
MDRaisedButton:
text: "Open date picker"
pos_hint: {'center_x': .5}
opposite_colors: True
on_release: app.show_example_date_picker()
MDLabel:
id: date_picker_label
halign: 'center'
BoxLayout:
size_hint: None, None
size: self.minimum_size
pos_hint: {'center_x': .5}
Label:
text: "Start on previous date"
size_hint_x: None
width: self.texture_size[0]
color: 0, 0, 0, 1
MDCheckbox:
id: date_picker_use_previous_date
size_hint: None, None
size: dp(48), dp(48)
"""
class Example(App):
theme_cls = ThemeManager()
pickers = None
previous_date = ''
def build(self):
Builder.load_string(KV)
self.pickers = Factory.Pickers()
return self.pickers
def show_example_date_picker(self, *args):
if self.pickers.ids.date_picker_use_previous_date.active:
pd = self.previous_date
try:
MDDatePicker(self.set_previous_date,
pd.year, pd.month, pd.day).open()
except AttributeError:
MDDatePicker(self.set_previous_date).open()
else:
MDDatePicker(self.set_previous_date).open()
def set_previous_date(self, date_obj):
self.previous_date = date_obj
self.pickers.ids.date_picker_label.text = str(date_obj)
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,81 @@
### Dialog on Android
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/dialog.gif)
### Dialog on iOS
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/dialog_ios.gif)
## Example of using a class MDDialogs:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.utils import get_hex_from_color
from kivymd.uix.dialog import MDInputDialog, MDDialog
from kivymd.theming import ThemeManager
Builder.load_string('''
<ExampleDialogs@BoxLayout>
orientation: 'vertical'
spacing: dp(5)
MDToolbar:
id: toolbar
title: app.title
left_action_items: [['menu', lambda x: None]]
elevation: 10
md_bg_color: app.theme_cls.primary_color
FloatLayout:
MDRectangleFlatButton:
text: "Open input dialog"
pos_hint: {'center_x': .5, 'center_y': .7}
opposite_colors: True
on_release: app.show_example_input_dialog()
MDRectangleFlatButton:
text: "Open Ok Cancel dialog"
pos_hint: {'center_x': .5, 'center_y': .5}
opposite_colors: True
on_release: app.show_example_okcancel_dialog()
''')
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Dialogs"
def build(self):
return Factory.ExampleDialogs()
def callback_for_menu_items(self, *args):
from kivymd.toast.kivytoast import toast
toast(args[0])
def show_example_input_dialog(self):
dialog = MDInputDialog(
title='Title', hint_text='Hint text', size_hint=(.8, .4),
text_button_ok='Yes',
events_callback=self.callback_for_menu_items)
dialog.open()
def show_example_okcancel_dialog(self):
dialog = MDDialog(
title='Title', size_hint=(.8, .3), text_button_ok='Yes',
text="Your [color=%s][b]text[/b][/color] dialog" % get_hex_from_color(
self.theme_cls.primary_color),
text_button_cancel='Cancel',
events_callback=self.callback_for_menu_items)
dialog.open()
if __name__ == "__main__":
Example().run()
```
In the dialog you can use two buttons:
**text_button_ok** and **text_button_cancel**
The library itself determines the platform and selects the desired type of windows for Android and iOS!

@ -0,0 +1,77 @@
![MDDropDownItem-with-ScrollView.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/MDDropDownItem-with-ScrollView.gif)
## Example of using MDDropDownItem-with-ScrollView:
```python
from kivy.app import App
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivymd.theming import ThemeManager
from kivymd.uix.dropdownitem import MDDropDownItem
from kivymd.uix.list import IRightBodyTouch, ThreeLineRightIconListItem
Builder.load_string(
"""
<Item>:
height: dp(56)
text: "A button with"
secondary_text: "a dropdown"
font_style: "H6"
ListButtonDropdown:
items: root.items
<Base>:
orientation: "vertical"
spacing: "10dp"
MDToolbar:
title: "Example MDDropDownItem with ScrollView"
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items: [["menu", lambda x: x]]
ScrollView:
GridLayout:
id: box
size_hint_y: None
height: self.minimum_height
cols: 1
"""
)
class Base(BoxLayout):
def __init__(self, **kwargs):
super(Base, self).__init__(**kwargs)
class Item(ThreeLineRightIconListItem):
items = ListProperty()
class ListButtonDropdown(IRightBodyTouch, MDDropDownItem):
pass
class SampleApp(App):
theme_cls = ThemeManager()
def build(self):
return Base()
def on_start(self):
for i in range(20):
self.root.ids.box.add_widget(
Item(items=[str(i+1), str(i+2), str(i+3)])
)
if __name__ == "__main__":
SampleApp().run()
```

@ -0,0 +1,51 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/dropdownitem.gif)
## Example of using MDDropDownItem:
```python
from kivy.app import App
from kivy.factory import Factory
from kivy.lang import Builder
from kivymd.theming import ThemeManager
Builder.load_string(
'''
#:import toast kivymd.toast.toast
<MyRoot@BoxLayout>
orientation: 'vertical'
MDToolbar:
title: "Test MDDropDownItem"
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items: [['menu', lambda x: x]]
FloatLayout:
MDDropDownItem:
id: dropdown_item
pos_hint: {'center_x': 0.5, 'center_y': 0.6}
items: app.items
dropdown_bg: [1, 1, 1, 1]
MDRaisedButton:
pos_hint: {'center_x': 0.5, 'center_y': 0.3}
text: 'Chek Item'
on_release: toast(dropdown_item.current_item)
''')
class Test(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = "BlueGray"
def build(self):
self.items = [f"Item {i}" for i in range(50)]
return Factory.MyRoot()
if __name__ == "__main__":
Test().run()
```

@ -0,0 +1,130 @@
> MDExpansionPanel will be added in KivyMD v0.101.0
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/accordionlistitem.gif)
## Example of using MDExpansionPanel:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.button import MDIconButton
from kivymd.uix.list import ILeftBodyTouch
from kivymd.theming import ThemeManager
from kivymd.uix.expansionpanel import MDExpansionPanel
from kivymd.toast import toast
Builder.load_string('''
#:import get_hex_from_color kivy.utils.get_hex_from_color
<ContentForAnimCard>
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
BoxLayout:
size_hint_y: None
height: self.minimum_height
Widget:
MDRoundFlatButton:
text: "Free call"
on_press: root.callback(self.text)
Widget:
MDRoundFlatButton:
text: "Free message"
on_press: root.callback(self.text)
Widget:
OneLineIconListItem:
text: "Video call"
on_press: root.callback(self.text)
IconLeftSampleWidget:
icon: 'camera-front-variant'
TwoLineIconListItem:
text: "Call Viber Out"
on_press: root.callback(self.text)
secondary_text:
"[color=%s]Advantageous rates for calls[/color]"\
% get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'phone'
TwoLineIconListItem:
text: "Call over mobile network"
on_press: root.callback(self.text)
secondary_text:
"[color=%s]Operator's tariffs apply[/color]"\
% get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'remote'
<ExampleExpansionPanel@BoxLayout>
orientation: 'vertical'
MDToolbar:
id: toolbar
title: app.title
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
elevation: 10
left_action_items: [['dots-vertical', lambda x: None]]
Screen:
ScrollView:
GridLayout:
id: anim_list
cols: 1
size_hint_y: None
height: self.minimum_height
''')
class ContentForAnimCard(BoxLayout):
callback = ObjectProperty(lambda x: None)
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
pass
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = "Example Expansion Panel"
main_widget = None
def build(self):
self.main_widget = Factory.ExampleExpansionPanel()
return self.main_widget
def on_start(self):
def callback(text):
toast(f'{text} to {content.name_item}')
content = ContentForAnimCard(callback=callback)
names_contacts = (
'Alexandr Taylor', 'Yuri Ivanov', 'Robert Patric', 'Bob Marley',
'Magnus Carlsen', 'Jon Romero', 'Anna Bell', 'Maxim Kramerer',
'Sasha Gray', 'Vladimir Ivanenko')
for name_contact in names_contacts:
self.main_widget.ids.anim_list.add_widget(
MDExpansionPanel(content=content,
icon='data/logo/kivy-icon-128.png',
title=name_contact))
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,206 @@
> Attention! This is an experimental widget.
> Perhaps the wrong positioning of the screens with a large number of them.
![fansceernmanager.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/fansceernmanager.gif)
## Example of using MDFanScreenManager:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.button import MDIconButton
from kivymd.uix.fanscreenmanager import MDFanScreen
from kivymd.uix.list import ILeftBodyTouch
from kivymd.theming import ThemeManager
Builder.load_string("""
#:import get_hex_from_color kivy.utils.get_hex_from_color
<TestFanScreenManager>:
orientation: 'vertical'
MDToolbar:
id: toolbar
title: 'Screen Tree'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: fan_screen_manager.open_fan()]]
background_palette: 'Primary'
MDFanScreenManager:
id: fan_screen_manager
canvas:
Color:
rgba: 0, 0, 0, .2
Rectangle:
pos: self.pos
size: self.size
ScreenOne:
name: 'Screen One'
on_enter: toolbar.title = self.name
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
ScreenTwo:
name: 'Screen Two'
on_enter: toolbar.title = self.name
ScreenTree:
name: 'Screen Tree'
on_enter: toolbar.title = self.name
canvas.before:
Color:
rgba: .9, .9, .8, 1
Rectangle:
pos: self.pos
size: self.size
###############################################################################
#
# SCREEN WIDGETS
#
###############################################################################
<ScreenTwo>:
orientation: 'vertical'
spacing: dp(10)
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'demos/kitchen_sink/assets/crop-blur.jpg'
Image:
source: 'demos/kitchen_sink/assets/twitter-red.png'
size_hint: None, None
size: dp(60), dp(60)
pos_hint: {'center_x': .5}
Label:
text: 'Registration'
size_hint_y: None
height: self.texture_size[1]
font_size: '20sp'
bold: True
Widget:
size_hint_y: None
height: dp(10)
MDTextFieldRect:
size_hint: None, None
size: root.width - dp(40), dp(30)
pos_hint: {'center_x': .5}
MDTextFieldRect:
size_hint: None, None
size: root.width - dp(40), dp(30)
pos_hint: {'center_x': .5}
Widget:
size_hint_y: None
height: dp(20)
Label:
text: 'Enter your Login and Password'
size_hint_y: None
height: self.texture_size[1]
AnchorLayout:
anchor_y: 'bottom'
padding: dp(10)
MDRoundFlatButton:
text: "Registration"
pos_hint: {'center_x': .5}
<ScreenOne>:
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
Image:
size_hint_y: None
source: 'data/logo/kivy-icon-512.png'
BoxLayout:
size_hint_y: None
height: self.minimum_height
Widget:
MDRoundFlatButton:
text: "Free call"
Widget:
MDRoundFlatButton:
text: "Free message"
Widget:
OneLineIconListItem:
text: "Video call"
IconLeftSampleWidget:
icon: 'camera-front-variant'
TwoLineIconListItem:
text: "Call Viber Out"
secondary_text:
"[color=%s]Advantageous rates for calls[/color]" \
% get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'phone'
TwoLineIconListItem:
text: "Call over mobile network"
secondary_text:
"[color=%s]Operator's tariffs apply[/color]" \
% get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'remote'
Widget:
""")
class TestFanScreenManager(BoxLayout):
pass
class ScreenOne(MDFanScreen):
pass
class ScreenTwo(MDFanScreen):
pass
class ScreenTree(ScreenOne):
pass
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
pass
class MyApp(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Red'
def build(self):
return TestFanScreenManager()
if __name__ == "__main__":
MyApp().run()
```

@ -0,0 +1,103 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/filemanager.gif)
## Example of using a class MDFileManager:
```python
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.modalview import ModalView
from kivymd.uix.filemanager import MDFileManager
from kivymd.theming import ThemeManager
from kivymd.toast import toast
Builder.load_string(
'''
<ExampleFileManager@BoxLayout>:
orientation: 'vertical'
spacing: dp(5)
MDToolbar:
id: toolbar
title: app.title
left_action_items: [['menu', lambda x: None]]
elevation: 10
md_bg_color: app.theme_cls.primary_color
FloatLayout:
MDRoundFlatIconButton:
text: "Open manager"
icon: "folder"
pos_hint: {'center_x': .5, 'center_y': .6}
on_release: app.file_manager_open()
''')
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "File Manager"
def __init__(self, **kwargs):
super(Example, self).__init__(**kwargs)
Window.bind(on_keyboard=self.events)
self.manager_open = False
self.manager = None
def build(self):
return Factory.ExampleFileManager()
def file_manager_open(self):
if not self.manager:
self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False)
self.file_manager = MDFileManager(
exit_manager=self.exit_manager, select_path=self.select_path)
self.manager.add_widget(self.file_manager)
self.file_manager.show('/') # output manager to the screen
self.manager_open = True
self.manager.open()
def select_path(self, path):
"""It will be called when you click on the file name
or the catalog selection button.
:type path: str;
:param path: path to the selected directory or file;
"""
self.exit_manager()
toast(path)
def exit_manager(self, *args):
"""Called when the user reaches the root of the directory tree."""
self.manager.dismiss()
self.manager_open = False
def events(self, instance, keyboard, keycode, text, modifiers):
"""Called when buttons are pressed on the mobile device.."""
if keyboard in (1001, 27):
if self.manager_open:
self.file_manager.back()
return True
if __name__ == "__main__":
Example().run()
```
## Example of using a class MDFileManager with previous mode:
(uses threads to create previews and does not slow down user interface)
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/filemanager_previous.gif)
```python
file_manager = MDFileManager(previous=True)
```

@ -0,0 +1,61 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/list-item-with-checkbox.gif)
## Example of using OneLineAvatarIconListItem with Checkbox:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.image import Image
from kivymd.theming import ThemeManager
from kivymd.uix.list import IRightBodyTouch, ILeftBody
from kivymd.uix.selectioncontrol import MDCheckbox
Builder.load_string(
'''
<ListItemWithCheckbox@OneLineAvatarIconListItem>:
MyAvatar:
source: 'data/logo/kivy-icon-128.png'
MyCheckbox:
<Lists@BoxLayout>
name: 'lists'
orientation: 'vertical'
MDToolbar:
title:'List item with Checkbox'
md_bg_color: app.theme_cls.primary_color
elevation: 10
ScrollView:
MDList:
id: scroll
''')
class MyCheckbox(IRightBodyTouch, MDCheckbox):
pass
class MyAvatar(ILeftBody, Image):
pass
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
def build(self):
list = Factory.Lists()
for i in range(30):
list.ids.scroll.add_widget(
Factory.ListItemWithCheckbox(text='Item %d' % i))
return list
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,208 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/custom-navigation-drawer.gif)
[CustomNavigationDrawer](https://github.com/HeaTTheatR/CustomNavigationDrawer)
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.animation import Animation
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.image import Image
from kivy.uix.screenmanager import Screen
from kivymd.uix.list import ILeftBody, OneLineAvatarListItem
from kivymd.theming import ThemableBehavior, ThemeManager
Builder.load_string("""
#:import Window kivy.core.window.Window
#:import get_hex_from_color kivy.utils.get_hex_from_color
#:set color_lilac_very_light [0.5215686274509804, 0.37254901960784315, 0.9450980392156862, 1]
#:set color_grey_dark [0.18823529411764706, 0.19215686274509805, 0.30980392156862746, 1]
#:set color_grey [.29411764705882354, .3215686274509804, .4196078431372549, 1]
#:set hex_color_grey get_hex_from_color([.29411764705882354, .3215686274509804, .4196078431372549, 1])
<MyLabel@Label>
size_hint: None, None
size: self.texture_size
pos_hint: {'center_x': .5}
<MyBoxLayout@BoxLayout>
size_hint_y: None
height: self.minimum_height
<CustomNavigationDrawerIconButton>
theme_text_color: 'Custom'
text_color: color_grey
divider: None
AvatarSampleWidget:
source: root.source
<CustomNavigationDrawer@BoxLayout>
size_hint: None, None
width: '360dp'
height: Window.height
x: Window.width
canvas:
Rectangle:
size: self.size
pos: self.pos
source: 'data/shadow-profile-items.png'
BoxLayout:
id: box_content
orientation: 'vertical'
width: '320dp'
pos_hint: {'right': 1}
padding: '60dp', '10dp', '30dp', 0
spacing: '30dp'
MDIconButton:
icon: 'close'
theme_text_color: 'Custom'
text_color: color_grey
on_release: root.parent.hide_navigation_drawer()
MyBoxLayout:
Image:
source: 'data/users/user.png'
MyLabel:
id: label_user_name_mail
markup: True
text:
f"[color={hex_color_grey}][size=20]HeaTTeatR" \
f"[/size][/color]\\nkivydevelopment@gmail.com"
color: color_grey_dark
pos_hint: {'center_y': .5}
MyBoxLayout:
spacing: '5dp'
padding: '10dp'
MyBoxLayout:
orientation: 'vertical'
spacing: '5dp'
MyLabel:
id: label_plain
markup: True
text: 'My Plain'
color: color_grey
pos_hint: {'center_y': .5}
MyBoxLayout:
spacing: '5dp'
Widget:
size_hint: None, None
size: '10dp', '10dp'
pos_hint: {'center_y': .5}
canvas.before:
Color:
rgba: color_lilac_very_light
RoundedRectangle:
size: self.size
pos: self.pos
MyLabel:
id: label_basic
markup: True
text: 'Basic $5/mo'
color: color_grey_dark
MDRoundFlatButton:
text: 'Upgrade'
pos_hint: {'right': 1}
ScrollView:
GridLayout:
id: box_item
cols: 1
size_hint_y: None
height: self.minimum_height
<RootScreen>
name: 'custom navigation drawer'
on_kv_post: root.set_navigation_drawer_icons()
FloatLayout:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: app.title
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items:
[['menu', lambda x: root.show_navigation_drawer()]]
Widget:
CustomNavigationDrawer:
id: navigation_drawer
""")
class AvatarSampleWidget(ILeftBody, Image):
pass
class CustomNavigationDrawerIconButton(OneLineAvatarListItem):
source = StringProperty()
class RootScreen(ThemableBehavior, Screen):
def hide_navigation_drawer(self):
Animation(x=Window.width, d=0.2).start(self.ids.navigation_drawer)
def show_navigation_drawer(self):
Animation(x=Window.width - self.ids.navigation_drawer.width, d=0.2).start(
self.ids.navigation_drawer
)
def set_navigation_drawer_icons(self):
for items in {
"home": "Home",
"about": "About",
"update": "Check for Update",
"preferences": "Preferences",
"promo": "Promo",
"report": "Send Report",
"out": "Sign Out",
"quit": "Quit",
}.items():
self.ids.navigation_drawer.ids.box_item.add_widget(
CustomNavigationDrawerIconButton(
text=items[1],
source=f"data/profile/{items[0]}.png",
)
)
class TestCustomNavigationDrawer(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = "Indigo"
root_screen = None
title = "Test CustomNavigationDrawer"
def build(self):
self.root_screen = RootScreen()
return self.root_screen
if __name__ == "__main__":
TestCustomNavigationDrawer().run()
```

@ -0,0 +1,87 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/custom-navigation-drawer-icon-button.gif)
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.image import Image
from kivymd.uix.list import ILeftBody, OneLineAvatarListItem
from kivymd.theming import ThemeManager
from kivymd.toast import toast
main_kv = """
<ContentNavigationDrawer@MDNavigationDrawer>
drawer_logo: 'demos/kitchen_sink/assets/drawer_logo.png'
NavigationDrawerSubheader:
text: "Menu:"
<CustomNavigationDrawerIconButton>
AvatarSampleWidget:
source: root.source
NavigationLayout:
id: nav_layout
ContentNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation: 'vertical'
MDToolbar:
id: toolbar
title: 'KivyMD Kitchen Sink'
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
background_hue: '500'
elevation: 10
left_action_items:
[['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
Widget:
"""
class AvatarSampleWidget(ILeftBody, Image):
pass
class CustomNavigationDrawerIconButton(OneLineAvatarListItem):
source = StringProperty()
def _set_active(self, active, nav_drawer):
pass
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Navigation Drawer"
main_widget = None
def build(self):
self.main_widget = Builder.load_string(main_kv)
return self.main_widget
def callback(self, instance, value):
toast("Pressed item menu %d" % value)
def on_start(self):
for i in range(15):
self.main_widget.ids.nav_drawer.add_widget(
CustomNavigationDrawerIconButton(
text=f"Item {i}",
source="data/logo/kivy-icon-128.png",
on_press=lambda x, y=i: self.callback(x, y)
)
)
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,157 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/navdrawer.gif)
## Example of using a class MDNavigationDrawer:
## Using MDNavigationDrawer has changed!
You should now use this markup structure:
```python
Root:
NavigationLayout:
ScreenManager:
...
...
MDNavigationDrawer:
UserContentNavigationDrawer:
```
`MDNavigationDrawer` is an empty `MDCard` class into which you add your own content.
```python
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineAvatarListItem
KV = '''
#:import IconLeftWidget kivymd.uix.list.IconLeftWidget
#:import images_path kivymd.images_path
<NavigationItem>
theme_text_color: 'Custom'
divider: None
IconLeftWidget:
icon: root.icon
<ContentNavigationDrawer>
BoxLayout:
orientation: 'vertical'
FloatLayout:
size_hint_y: None
height: "200dp"
canvas:
Color:
rgba: app.theme_cls.primary_color
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
id: top_box
size_hint_y: None
height: "200dp"
#padding: "10dp"
x: root.parent.x
pos_hint: {"top": 1}
FitImage:
source: f"{images_path}kivymd_alpha.png"
MDIconButton:
icon: "close"
x: root.parent.x + dp(10)
pos_hint: {"top": 1}
on_release: root.parent.toggle_nav_drawer()
MDLabel:
markup: True
text: "[b]KivyMD[/b]\\nVersion: 0.102.1"
#pos_hint: {'center_y': .5}
x: root.parent.x + dp(10)
y: root.height - top_box.height + dp(10)
size_hint_y: None
height: self.texture_size[1]
ScrollView:
pos_hint: {"top": 1}
GridLayout:
id: box_item
cols: 1
size_hint_y: None
height: self.minimum_height
Screen:
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "Navigation Drawer"
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.toggle_nav_drawer()]]
Widget:
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
id: content_drawer
'''
class ContentNavigationDrawer(BoxLayout):
pass
class NavigationItem(OneLineAvatarListItem):
icon = StringProperty()
class TestNavigationDrawer(MDApp):
def build(self):
return Builder.load_string(KV)
def on_start(self):
for items in {
"home-circle-outline": "Home",
"update": "Check for Update",
"settings-outline": "Settings",
"exit-to-app": "Exit",
}.items():
self.root.ids.content_drawer.ids.box_item.add_widget(
NavigationItem(
text=items[1],
icon=items[0],
)
)
TestNavigationDrawer().run()
```

@ -0,0 +1,84 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/progressloader.gif)
## Example of using a class MDProgressLoader:
```python
import os
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.uix.progressloader import MDProgressLoader
from kivymd.theming import ThemeManager
from kivymd.toast import toast
Builder.load_string(
'''
<Root@BoxLayout>:
orientation: 'vertical'
spacing: dp(5)
MDToolbar:
id: toolbar
title: app.title
left_action_items: [['menu', lambda x: None]]
elevation: 10
md_bg_color: app.theme_cls.primary_color
FloatLayout:
id: box
MDRoundFlatIconButton:
text: "Download file"
icon: "download"
pos_hint: {'center_x': 0.5, 'center_y': 0.6}
on_release: app.show_example_download_file()
''')
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Progress Loader"
def build(self):
self.main_widget = Factory.Root()
return self.main_widget
def set_chevron_back_screen(self):
'''Sets the return chevron to the previous screen in ToolBar.'''
self.main_widget.ids.toolbar.right_action_items = []
def download_progress_hide(self, instance_progress, value):
'''Hides progress progress.'''
self.main_widget.ids.toolbar.right_action_items = \
[['download',
lambda x: self.download_progress_show(instance_progress)]]
def download_progress_show(self, instance_progress):
self.set_chevron_back_screen()
instance_progress.open()
instance_progress.animation_progress_from_fade()
def show_example_download_file(self):
link = 'https://www.python.org/ftp/python/3.5.1/python-3.5.1-embed-win32.zip'
progress = MDProgressLoader(
url_on_image=link,
path_to_file=os.path.join(self.directory, 'python-3.5.1.zip'),
download_complete=self.download_complete,
download_hide=self.download_progress_hide
)
progress.start(self.main_widget.ids.box)
def download_complete(self):
self.set_chevron_back_screen()
toast('Done')
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,96 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/refesh-layout.gif)
## Example of using a class MDScrollViewRefreshLayout:
```python
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.properties import StringProperty
from kivymd.uix.button import MDIconButton
from kivymd.icon_definitions import md_icons
from kivymd.uix.list import ILeftBodyTouch, OneLineIconListItem
from kivymd.theming import ThemeManager
Builder.load_string('''
<ItemForList>
text: root.text
IconLeftSampleWidget:
icon: root.icon
<Example@FloatLayout>
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: app.title
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
elevation: 10
left_action_items: [['menu', lambda x: x]]
MDScrollViewRefreshLayout:
id: refresh_layout
refresh_callback: app.refresh_callback
root_layout: root
GridLayout:
id: box
size_hint_y: None
height: self.minimum_height
cols: 1
''')
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
pass
class ItemForList(OneLineIconListItem):
icon = StringProperty()
class Example(App):
title = 'Example Refresh Layout'
theme_cls = ThemeManager()
screen = None
x = 0
y = 15
def build(self):
self.screen = Factory.Example()
self.set_list()
return self.screen
def set_list(self):
names_icons_list = list(md_icons.keys())[self.x:self.y]
for name_icon in names_icons_list:
self.screen.ids.box.add_widget(
ItemForList(icon=name_icon, text=name_icon))
def refresh_callback(self, *args):
"""A method that updates the state of your application
while the spinner remains on the screen."""
def refresh_callback(interval):
self.screen.ids.box.clear_widgets()
if self.x == 0:
self.x, self.y = 15, 30
else:
self.x, self.y = 0, 15
self.set_list()
self.screen.ids.refresh_layout.refresh_done()
self.tick = 0
Clock.schedule_once(refresh_callback, 1)
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,70 @@
![sliders.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/sliders.gif)
## Example of using MDSlider and MDProgressBar:
```python
from kivy.app import App
from kivymd.theming import ThemeManager
class SliderApp(App):
theme_cls = ThemeManager()
def build(self):
return Builder.load_string(
"""
Screen
name: 'progress bar'
BoxLayout:
orientation:'vertical'
padding: '8dp'
MDLabel:
text: "Slider with [b]hint = True[/b]"
markup: True
halign: "center"
MDSlider:
id: progress_slider
min: 0
max: 100
value: 40
MDLabel:
text: "Slider with [b]hint = False[/b]"
markup: True
halign: "center"
MDSlider:
id: progress_slider
min: 0
max: 100
value: 40
hint: False
MDLabel:
text: "Examples [b]MDProgressBar[/b]"
markup: True
halign: "center"
MDProgressBar:
value: progress_slider.value
MDProgressBar:
reversed: True
value: progress_slider.value
BoxLayout:
MDProgressBar:
orientation: "vertical"
reversed: True
value: progress_slider.value
MDProgressBar:
orientation: "vertical"
value: progress_slider.value
"""
)
SliderApp().run()
```

@ -0,0 +1,123 @@
![grid.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/grid.gif)
## Example of using MDSmatrTiles:
```python
import os
from kivy.app import App
from kivy.lang import Builder
from kivymd.theming import ThemeManager
from kivymd.utils.cropimage import crop_image
kv = """
<MySmartTileWithLabel@SmartTileWithLabel>:
mipmap: True
font_style: 'Subhead'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: app.title
elevation: 10
left_action_items: [['menu', lambda x: x]]
md_bg_color: app.theme_cls.primary_color
ScreenManager:
id: manager
Screen:
name: 'one'
MDRaisedButton:
pos_hint: {'center_x': .5, 'center_y': .55}
on_release: manager.current = 'two'
text: 'Open Grid'
Screen:
name: 'two'
on_enter:
app.crop_image_for_tile(tile_1, tile_1.size, \
'demos/kitchen_sink/assets/beautiful-931152_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_2, tile_2.size, \
'demos/kitchen_sink/assets/african-lion-951778_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_3, tile_3.size, \
'demos/kitchen_sink/assets/guitar-1139397_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_4, tile_4.size, \
'demos/kitchen_sink/assets/robin-944887_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_5, tile_5.size, \
'demos/kitchen_sink/assets/kitten-1049129_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_6, tile_6.size, \
'demos/kitchen_sink/assets/light-bulb-1042480_1280_tile_crop.jpg')
app.crop_image_for_tile(tile_7, tile_7.size, \
'demos/kitchen_sink/assets/tangerines-1111529_1280_tile_crop.jpg')
ScrollView:
do_scroll_x: False
GridLayout:
cols: 2
row_default_height:
(self.width - self.cols*self.spacing[0])/self.cols
row_force_default: True
size_hint_y: None
height: self.minimum_height
padding: dp(4), dp(4)
spacing: dp(4)
SmartTileWithStar:
id: tile_2
mipmap: True
stars: 3
SmartTileWithStar:
id: tile_3
mipmap: True
stars: 3
SmartTileWithLabel:
id: tile_1
text:
"Beautiful\\n[size=12]beautiful-931152_1280.jpg[/size]"
SmartTileWithLabel:
id: tile_4
text:
"Robin\\n[size=12]robin-944887_1280.jpg[/size]"
SmartTileWithLabel:
id: tile_5
text:
"Kitten\\n[size=12]kitten-1049129_1280.jpg[/size]"
SmartTileWithLabel:
id: tile_6
text:
"Light-Bulb\\n[size=12]light-bulb-1042480_1280.jpg[/size]"
SmartTileWithLabel:
id: tile_7
text:
"Tangerines\\n[size=12]tangerines-1111529_1280.jpg[/size]"
"""
class MyApp(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = 'Example Smart Tile'
md_app_bar = None
def build(self):
root = Builder.load_string(kv)
return root
def crop_image_for_tile(self, instance, size, path_to_crop_image):
if not os.path.exists(
os.path.join(self.directory, path_to_crop_image)):
size = (int(size[0]), int(size[1]))
path_to_origin_image = path_to_crop_image.replace('_tile_crop', '')
crop_image(size, path_to_origin_image, path_to_crop_image)
instance.source = path_to_crop_image
if __name__ == "__main__":
MyApp().run()
```

@ -0,0 +1,191 @@
![chips.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/snackbar.gif)
## Example of using Snackbars:
```python
from kivy.app import App
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.metrics import dp
from kivy.lang import Builder
from kivymd.uix.snackbar import Snackbar
from kivymd.theming import ThemeManager
from kivymd.toast import toast
KV = """
#:import Window kivy.core.window.Window
Screen:
name: 'snackbar'
BoxLayout:
orientation: 'vertical'
spacing: dp(10)
MDToolbar:
title: 'Example Snackbar'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: x]]
background_palette: 'Primary'
BoxLayout:
orientation: 'vertical'
spacing: dp(10)
padding: dp(10)
Widget:
MDRaisedButton:
text: "Create simple snackbar"
pos_hint: {'center_x': .5}
on_release: app.show_example_snackbar('simple')
MDRaisedButton:
text: "Create snackbar with button"
pos_hint: {'center_x': .5}
on_release: app.show_example_snackbar('button')
MDRaisedButton:
text: "Create snackbar with a lot of text"
pos_hint: {'center_x': .5}
on_release: app.show_example_snackbar('verylong')
MDSeparator:
MDLabel:
text: 'Click the MDFloatingActionButton to show the following example...'
halign: 'center'
Widget:
MDFloatingActionButton:
id: button
md_bg_color: app.theme_cls.primary_color
x: Window.width - self.width - dp(10)
y: dp(10)
on_release: app.show_example_snackbar('float')
"""
class ExampleSnackBar(App):
theme_cls = ThemeManager()
_interval = 0
my_snackbar = None
screen = None
def build(self):
self.screen = Builder.load_string(KV)
return self.screen
def show_example_snackbar(self, snack_type):
def callback(instance):
toast(instance.text)
def wait_interval(interval):
self._interval += interval
if self._interval > self.my_snackbar.duration:
anim = Animation(y=dp(10), d=.2)
anim.start(self.screen.ids.button)
Clock.unschedule(wait_interval)
self._interval = 0
self.my_snackbar = None
if snack_type == 'simple':
Snackbar(text="This is a snackbar!").show()
elif snack_type == 'button':
Snackbar(text="This is a snackbar", button_text="with a button!",
button_callback=callback).show()
elif snack_type == 'verylong':
Snackbar(text="This is a very very very very very very very "
"long snackbar!").show()
elif snack_type == 'float':
if not self.my_snackbar:
self.my_snackbar = Snackbar(
text="This is a snackbar!", button_text='Button',
duration=3, button_callback=callback)
self.my_snackbar.show()
anim = Animation(y=dp(72), d=.2)
anim.bind(on_complete=lambda *args: Clock.schedule_interval(
wait_interval, 0))
anim.start(self.screen.ids.button)
if __name__ == "__main__":
ExampleSnackBar().run()
```
## Example of using MDFloatingActionButton with Snackbars:
![chips.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/snackbar-2.gif)
```python
from kivy.app import App
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.metrics import dp
from kivy.lang import Builder
from kivymd.uix.snackbar import Snackbar
from kivymd.theming import ThemeManager
from kivymd.toast import toast
KV = """
#:import Window kivy.core.window.Window
Screen:
name: 'snackbar'
Toolbar:
title: 'Example Snackbar'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: x]]
pos_hint: {'top': 1}
MDFloatingActionButton:
id: button
md_bg_color: app.theme_cls.primary_color
x: Window.width - self.width - dp(10)
y: dp(10)
on_release: app.show_example_snackbar('float')
"""
class ExampleSnackBar(App):
theme_cls = ThemeManager()
_interval = 0
my_snackbar = None
screen = None
def build(self):
self.screen = Builder.load_string(KV)
return self.screen
def show_example_snackbar(self, snack_type):
def callback(instance):
toast(instance.text)
def wait_interval(interval):
self._interval += interval
if self._interval > self.my_snackbar.duration:
anim = Animation(y=dp(10), d=.2)
anim.start(self.screen.ids.button)
Clock.unschedule(wait_interval)
self._interval = 0
self.my_snackbar = None
if not self.my_snackbar:
self.my_snackbar = Snackbar(
text="This is a snackbar!", button_text='Button',
duration=3, button_callback=callback)
self.my_snackbar.show()
anim = Animation(y=dp(72), d=.2)
anim.bind(on_complete=lambda *args: Clock.schedule_interval(wait_interval, 0))
anim.start(self.screen.ids.button)
if __name__ == "__main__":
ExampleSnackBar().run()
```

@ -0,0 +1,55 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/stackfloatingbuttons.gif)
## Example of using a class MDStackFloatingButtons:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.toast import toast
from kivymd.theming import ThemeManager
from kivymd.uix.stackfloatingbutton import MDStackFloatingButtons
Builder.load_string("""
<ExampleFloatingButtons@BoxLayout>:
orientation: 'vertical'
MDToolbar:
title: 'Stack Floating Buttons'
md_bg_color: app.theme_cls.primary_color
elevation: 10
left_action_items: [['menu', lambda x: None]]
""")
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Example Stack Floating Buttons"
create_stack_floating_buttons = False
floating_data = {
'Python': 'language-python',
'Php': 'language-php',
'C++': 'language-cpp'}
def set_my_language(self, instance_button):
toast(instance_button.icon)
def build(self):
screen = Factory.ExampleFloatingButtons()
# Use this condition otherwise the stack will be created each time.
if not self.create_stack_floating_buttons:
screen.add_widget(MDStackFloatingButtons(
icon='lead-pencil',
floating_data=self.floating_data,
callback=self.set_my_language))
self.create_stack_floating_buttons = True
return screen
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,154 @@
![managerswiper.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/managerswiper.gif)
## Example of using MDSwiperManager:
```python
import os
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.card import MDCard
from kivymd.uix.managerswiper import MDSwiperPagination
from kivymd.theming import ThemeManager
from kivymd.utils.cropimage import crop_image
activity = '''
#:import images_path kivymd.images_path
<MyCard>:
orientation: 'vertical'
size_hint_y: None
height: dp(300)
pos_hint: {'top': 1}
Image:
source:
'{}/demos/kitchen_sink/assets/' \
'guitar-1139397_1280_swiper_crop.png'.format(app.directory)
size_hint: None, None
size: root.width, dp(250)
pos_hint: {'top': 1}
MDLabel:
theme_text_color: 'Custom'
bold: True
text_color: app.theme_cls.primary_color
text: root.text
size_hint_y: None
height: dp(60)
halign: 'center'
<ScreenOne@Screen>:
name: 'screen one'
MyCard:
text: 'Swipe to switch to screen one'.upper()
<ScreenTwo@Screen>:
name: 'screen two'
MyCard:
text: 'Swipe to switch to screen two'.upper()
<ScreenThree@Screen>:
name: 'screen three'
MyCard:
text: 'Swipe to switch to screen three'.upper()
<ScreenFour@Screen>:
name: 'screen four'
MyCard:
text: 'Swipe to switch to screen four'.upper()
<ScreenFive@Screen>:
name: 'screen five'
MyCard:
text: 'Swipe to switch to screen five'.upper()
<MySwiperManager>:
orientation: 'vertical'
canvas:
Color:
rgba: 0, 0, 0, .2
Rectangle:
pos: self.pos
size: self.size
MDToolbar:
id: toolbar
title: 'Swiper Manager'
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
elevation: 10
left_action_items: [['menu', lambda x: x]]
BoxLayout:
padding: dp(10)
orientation: 'vertical'
MDSwiperManager:
id: swiper_manager
ScreenOne:
ScreenTwo:
ScreenThree:
ScreenFour:
ScreenFive:
'''
class MySwiperManager(BoxLayout):
pass
class MyCard(MDCard):
text = StringProperty('')
class Test(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Indigo'
swiper_manager = None
def build(self):
self.crop_image_for_card()
Builder.load_string(activity)
start_screen = MySwiperManager()
self.swiper_manager = start_screen.ids.swiper_manager
paginator = MDSwiperPagination()
paginator.screens = self.swiper_manager.screen_names
paginator.manager = self.swiper_manager
self.swiper_manager.paginator = paginator
start_screen.add_widget(paginator)
return start_screen
def crop_image_for_card(self):
path_to_crop_image = \
'{}/demos/kitchen_sink/assets/' \
'guitar-1139397_1280_swiper_crop.png'.format(self.directory)
if not os.path.exists(path_to_crop_image):
crop_image(
(int(Window.width - dp(10)), int(dp(250))),
'{}/demos/kitchen_sink/assets/guitar-1139397_1280.png'.format(
self.directory), path_to_crop_image)
if __name__ == '__main__':
Test().run()
```

@ -0,0 +1,97 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/tabs.gif)
## Example of using MDTabs:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.icon_definitions import md_icons
from kivymd.uix.tabs import MDTabsBase
from kivymd.theming import ThemeManager
demo = """
<Example@BoxLayout>
orientation: 'vertical'
MDToolbar:
title: app.title
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
left_action_items: [['menu', lambda x: x]]
MDTabs:
id: android_tabs
<MyTab>
FloatLayout:
MDLabel:
text: 'Content'
halign: 'center'
font_style: 'H6'
"""
if __name__ == '__main__':
from kivy.factory import Factory
from kivymd.button import MDIconButton
class MyTab(BoxLayout, MDTabsBase):
pass
class Example(App):
title = 'Example Tabs'
theme_cls = ThemeManager()
list_name_icons = list(md_icons.keys())[0:15]
def build(self):
Builder.load_string(demo)
screen = Factory.Example()
for name_tab in self.list_name_icons:
tab = MyTab(text=name_tab)
screen.ids.android_tabs.add_widget(tab)
return screen
Example().run()
```
If you want to use text instead of icons in tabs, simply assign a text value to the **text** parameter in **MDTab**, which is not in the **md_icon** dictionary:
```python
def build(self):
...
for name_tab in self.list_name_icons:
tab = MyTab(text=' '.join(name_tab.split('-')).capitalize())
screen.ids.android_tabs.add_widget(tab)
```
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/tabs-text.gif)
## AndroidTabs properties
- *default_tab* - Index of the default tab. NumericProperty(0)
- *tab_bar_height* - Height of the tab bar. NumericProperty('48dp')
- *tab_indicator_anim* - Tab indicator animation. BooleanProperty(True)
- *tab_indicator_height* - Height of the tab indicator. NumeriProperty('2dp')
- *anim_duration* - Duration of the slide animation. NumericProperty(0.2)
- *anim_threshold* - Accepts 0.0 to 1.0 and directly affects indicator animation effect. BoundedNumeriProperty(0.8)
## AndroidTabsLabel properties
- *text_color_normal* - Text color of the label when it is not selected. VariableListProperty([1, 1, 1, .6])
- *text_color_active* - Text color of the label when it is selected. VariableListProperty([1])
## Original AndroidTabs library
https://github.com/kivy-garden/garden.androidtabs

@ -0,0 +1,98 @@
![textfieldrect.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/textfieldrect.gif)
## Example of using MDTextFieldRect:
```python
import os
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.core.window import Window
from kivymd.theming import ThemeManager
from kivymd.utils.cropimage import crop_image
Builder.load_string("""
<ExampleMDTextFieldRect@BoxLayout>:
orientation: 'vertical'
spacing: dp(10)
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'demos/kitchen_sink/assets/crop-blur.jpg'
Image:
source: 'demos/kitchen_sink/assets/twitter-red.png'
size_hint: None, None
size: dp(60), dp(60)
pos_hint: {'center_x': .5}
Label:
text: 'Registration'
size_hint_y: None
height: self.texture_size[1]
font_size: '20sp'
bold: True
Widget:
size_hint_y: None
height: dp(10)
MDTextFieldRect:
size_hint: None, None
size: root.width - dp(40), dp(30)
pos_hint: {'center_x': .5}
MDTextFieldRect:
size_hint: None, None
size: root.width - dp(40), dp(30)
pos_hint: {'center_x': .5}
Widget:
size_hint_y: None
height: dp(20)
Label:
text: 'Enter your Login and Password'
size_hint_y: None
height: self.texture_size[1]
AnchorLayout:
anchor_y: 'bottom'
padding: dp(10)
MDRoundFlatButton:
text: "Registration"
pos_hint: {'center_x': .5}
""")
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Red'
title = "Example MDTextFieldRect"
main_widget = None
def __init__(self, **kwargs):
super(Example, self).__init__(**kwargs)
path_to_crop_image = \
'{}/demos/kitchen_sink/assets/crop-blur.jpg'.format(self.directory)
path_to_origin_image = \
'{}/demos/kitchen_sink/assets/blur.jpg'.format(self.directory)
if not os.path.exists(path_to_crop_image):
crop_image((Window.width, Window.height),
path_to_origin_image,
path_to_crop_image)
def build(self):
self.main_widget = Factory.ExampleMDTextFieldRect()
return self.main_widget
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,177 @@
![textfieldrect.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/md-text-field-round.gif)
## Example of using MDTextFieldRound:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.theming import ThemeManager
Builder.load_string('''
#:set color_shadow [0, 0, 0, .2980392156862745]
#:set color_lilac [.07058823529411765, .07058823529411765, .14901960784313725, .8]
<MyMDTextFieldRound@MDTextFieldRound>
size_hint_x: None
normal_color: color_shadow
active_color: color_shadow
pos_hint: {'center_x': .5}
<Example@Screen>
canvas:
Color:
rgba: color_lilac
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
spacing: dp(15)
pos_hint: {'center_x': .5, 'center_y': .5}
MyMDTextFieldRound:
icon_type: 'without'
hint_text: 'Field with `normal_color`'
normal_color: [0, 0, 0, .1]
MyMDTextFieldRound:
icon_type: 'without'
hint_text: 'Field without icon'
MyMDTextFieldRound:
icon_type: 'without'
hint_text: 'Field with `require_text_error`'
require_text_error: 'Field must be not empty!'
MyMDTextFieldRound:
icon_left: 'email'
icon_type: 'left'
hint_text: 'Field with left icon'
MyMDTextFieldRound:
icon_left: 'email'
icon_right: 'account-box'
icon_right_disabled: True
hint_text: 'Field with left and right disabled icons'
MyMDTextFieldRound:
icon_type: 'all'
icon_left: 'key-variant'
icon_right: 'eye-off'
icon_right_disabled: False
icon_callback: app.show_password
password: True
hint_text: 'Field width type `password = True`'
''')
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'BlueGray'
def build(self):
return Factory.Example()
def show_password(self, field, button):
"""
Called when you press the right button in the password field
for the screen TextFields.
instance_field: kivy.uix.textinput.TextInput;
instance_button: kivymd.button.MDIconButton;
"""
# Show or hide text of password, set focus field
# and set icon of right button.
field.password = not field.password
field.focus = True
button.icon = 'eye' if button.icon == 'eye-off' else 'eye-off'
if __name__ == '__main__':
Example().run()
```
## Parameters:
```python
width = NumericProperty(Window.width - dp(100))
'''Text field width.'''
icon_left = StringProperty('email-outline')
'''Left icon.'''
icon_right = StringProperty('email-outline')
'''Right icon.'''
icon_type = OptionProperty(
'none', options=['right', 'left', 'all', 'without'])
'''Use one (left) or two (left and right) icons in the text field.'''
hint_text = StringProperty()
'''Hint text in the text field.'''
hint_text_color = ListProperty()
'''Color of hint text in the text field.'''
icon_color = ListProperty([1, 1, 1, 1])
'''Color of icons.'''
active_color = ListProperty([1, 1, 1, .2])
'''The color of the text field when it is in focus.'''
normal_color = ListProperty([1, 1, 1, .5])
'''The color of the text field when it not in focus.'''
foreground_color = ListProperty([1, 1, 1, 1])
'''Text color.'''
hint_text_color = ListProperty([0.5, 0.5, 0.5, 1.0])
'''Text field hint color.'''
cursor_color = ListProperty()
'''Color of cursor'''
selection_color = ListProperty()
'''Text selection color.'''
icon_callback = ObjectProperty()
'''The function that is called when you click on the icon
in the text field.'''
text = StringProperty()
'''Text of field.'''
icon_left_dasabled = BooleanProperty(False)
'''Disable the left icon.'''
icon_right_disabled = BooleanProperty(False)
'''Disable the right icon.'''
password = BooleanProperty(False)
'''Hide text or notю'''
password_mask = StringProperty('*')
'''Characters on which the text will be replaced
if the `password` is True.'''
require_text_error = StringProperty()
'''Error text if the text field requires mandatory text.'''
require_error_callback = ObjectProperty()
'''The function that will be called when the unfocus.
  if `require_text_error` != ''
'''
event_focus = ObjectProperty()
'''The function is called at the moment of focus/unfocus of the text field.
'''
```

@ -0,0 +1,103 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/textfield_cleartype.gif)
## Example of using TextFields:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.theming import ThemeManager
Builder.load_string("""
<ExampleTextFields@BoxLayout>:
orientation: 'vertical'
Toolbar:
id: toolbar
title: app.title
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
elevation: 10
left_action_items: [['dots-vertical', lambda x: None]]
ScrollView:
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
MDTextField:
hint_text: "Persistent helper text"
helper_text: "Text is always here"
helper_text_mode: "persistent"
MDTextField:
id: text_field_error
hint_text:
"Helper text on error (Hit Enter with two characters here)"
helper_text: "Two is my least favorite number"
helper_text_mode: "on_error"
MDTextField:
hint_text: "Max text length = 10"
max_text_length: 10
MDTextField:
hint_text: "required = True"
required: True
helper_text_mode: "on_error"
MDTextField:
multiline: True
hint_text: "Multi-line text"
helper_text: "Messages are also supported here"
helper_text_mode: "persistent"
MDTextField:
hint_text: "color_mode = \'accent\'"
color_mode: 'accent'
MDTextField:
hint_text: "color_mode = \'custom\'"
color_mode: 'custom'
helper_text_mode: "on_focus"
helper_text:
"Color is defined by \'line_color_focus\' property"
line_color_focus:
# This is the color used by the textfield
self.theme_cls.opposite_bg_normal
MDTextField:
hint_text: "disabled = True"
disabled: True
MDTextFieldClear:
hint_text: "Text field with clearing type"
""")
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = "Example Text Fields"
main_widget = None
def build(self):
return Factory.ExampleTextFields()
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,81 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/time-picker.gif)
## Example of using MDTimePicker:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.theming import ThemeManager
KV = """
<Pickers@Screen>
name: 'pickers'
BoxLayout:
orientation: 'vertical'
spacing: dp(20)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint_y: None
height: self.minimum_height
MDRaisedButton:
text: "Open time picker"
pos_hint: {'center_x': .5}
on_release: app.show_example_time_picker()
MDLabel:
id: time_picker_label
halign: 'center'
BoxLayout:
size_hint: None, None
size: self.minimum_size
pos_hint: {'center_x': .5}
Label:
text: "Start on previous date"
size_hint_x: None#, None
width: self.texture_size[0]
color: 0, 0, 0, 1
MDCheckbox:
id: time_picker_use_previous_time
size_hint: None, None
size: dp(48), dp(48)
"""
class Example(App):
theme_cls = ThemeManager()
pickers = None
previous_time = ''
def build(self):
Builder.load_string(KV)
self.pickers = Factory.Pickers()
return self.pickers
def show_example_time_picker(self):
from kivymd.pickers import MDTimePicker
time_dialog = MDTimePicker()
time_dialog.bind(time=self.get_time_picker_date)
if self.pickers.ids.time_picker_use_previous_time.active:
try:
time_dialog.set_time(self.previous_time)
except AttributeError:
pass
time_dialog.open()
def get_time_picker_date(self, instance, time):
self.pickers.ids.time_picker_label.text = str(time)
self.previous_time = time
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,74 @@
![chips.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/tooltips.gif)
## Example of using MDTooltips:
```python
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.app import MDApp
Builder.load_string("""
#:import random random
#:import hex_colormap kivy.utils.hex_colormap
#:import get_color_from_hex kivy.utils.get_color_from_hex
#:import md_icons kivymd.icon_definitions.md_icons
#:set ICONS list(md_icons.keys())
<IconButtonTooltips@MDIconButton+MDTooltip>
<ExampleTooltips@BoxLayout>
orientation: 'vertical'
MDToolbar:
title: "Example Tooltips"
md_bg_color: get_color_from_hex(hex_colormap["crimson"])
elevation: 10
left_action_items: [['dots-vertical', lambda x: None]]
tooltip_text: "MDToolbar"
Screen:
BoxLayout:
size_hint: None, None
size: self.minimum_size
padding: "10dp"
spacing: "10dp"
pos_hint: {'center_x': .5, "center_y": .9}
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
IconButtonTooltips:
icon: random.choice(ICONS)
tooltip_text: "MDIconButton"
""")
class Test(MDApp):
def build(self):
return Factory.ExampleTooltips()
Test().run()
```
## MDTooltip Behavior on Mobile:
![chips.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/tooltips-on-mobile.gif)

@ -0,0 +1,88 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/useranimationcard.gif)
## Example of using a class MDUserAnimationCard:
```python
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.toast import toast
from kivymd.theming import ThemeManager
from kivymd.uix.useranimationcard import MDUserAnimationCard
from kivymd.uix.button import MDIconButton
from kivymd.uix.list import ILeftBodyTouch
# Your content for a contact card.
Builder.load_string("""
#:import get_hex_from_color kivy.utils.get_hex_from_color
<TestAnimationCard@BoxLayout>:
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
BoxLayout:
size_hint_y: None
height: self.minimum_height
Widget:
MDRoundFlatButton:
text: "Free call"
Widget:
MDRoundFlatButton:
text: "Free message"
Widget:
OneLineIconListItem:
text: "Video call"
IconLeftSampleWidget:
icon: 'camera-front-variant'
TwoLineIconListItem:
text: "Call Viber Out"
secondary_text: "[color=%s]Advantageous rates for calls[/color]" % get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'phone'
TwoLineIconListItem:
text: "Call over mobile network"
secondary_text: "[color=%s]Operator's tariffs apply[/color]" % get_hex_from_color(app.theme_cls.primary_color)
IconLeftSampleWidget:
icon: 'remote'
""")
class IconLeftSampleWidget(ILeftBodyTouch, MDIconButton):
pass
class Example(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Teal'
title = "Example Animation Card"
def __init__(self, **kwargs):
super(Example, self).__init__(**kwargs)
self.user_animation_card = None
def build(self):
def main_back_callback():
toast('Close card')
if not self.user_animation_card:
self.user_animation_card = MDUserAnimationCard(
user_name="User Name",
path_to_avatar="path_to_avatar",
callback=main_back_callback)
self.user_animation_card.box_content.add_widget(
Factory.TestAnimationCard())
self.user_animation_card.open()
if __name__ == "__main__":
Example().run()
```

@ -0,0 +1,43 @@
![useranimationcard.gif](https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivy-toast.gif)
## Example of using Kivy Toast:
```python
from kivy.app import App
from kivymd.theming import ThemeManager
from kivymd.toast.kivytoast.kivytoast import toast
class Test(App):
theme_cls = ThemeManager()
def show_toast(self):
toast('Test Kivy Toast')
# toast('Test Kivy Toast', duration=3) # toast with user duration
def build(self):
return Builder.load_string(
'''
BoxLayout:
orientation:'vertical'
MDToolbar:
id: toolbar
title: 'Test Toast'
md_bg_color: app.theme_cls.primary_color
left_action_items: [['menu', lambda x: '']]
FloatLayout:
MDRaisedButton:
text: 'TEST KIVY TOAST'
on_release: app.show_toast()
pos_hint: {'center_x': .5, 'center_y': .5}
'''
)
if __name__ == "__main__":
Test().run()
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

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

Loading…
Cancel
Save