updates
@ -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="""" />
|
||||
<option name="_new_parameters" value=""--cov\u003dkivymd --cov-report\u003dterm"" />
|
||||
<option name="_new_additionalArguments" value="""" />
|
||||
<option name="_new_target" value=""kivymd/tests"" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<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]
|
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 585 KiB |
After Width: | Height: | Size: 165 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 270 KiB |
After Width: | Height: | Size: 270 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 517 B |
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 392 B |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 520 KiB |
After Width: | Height: | Size: 216 KiB |
After Width: | Height: | Size: 442 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 41 KiB |
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,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()
|
||||
```
|
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 51 KiB |