first commit
This commit is contained in:
commit
417e54da96
5696 changed files with 900003 additions and 0 deletions
|
@ -0,0 +1,4 @@
|
|||
from .segmentedbutton import ( # NOQA F401
|
||||
MDSegmentedButton,
|
||||
MDSegmentedButtonItem,
|
||||
)
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,32 @@
|
|||
<MDSegmentedButton>
|
||||
size_hint: None, None
|
||||
height: "40dp"
|
||||
opacity: 0
|
||||
|
||||
|
||||
<MDSegmentedButtonItem>
|
||||
size_hint: None, None
|
||||
height: self.parent.height
|
||||
line_color:
|
||||
self.theme_cls.disabled_hint_text_color \
|
||||
if self.parent.line_color == [0, 0, 0, 0] else \
|
||||
self.parent.line_color
|
||||
|
||||
SegmentButtonIcon:
|
||||
id: scale_icon
|
||||
icon: root.icon
|
||||
size_hint: None, None
|
||||
size: "24dp", "24dp"
|
||||
pos_hint: {"center_y": .5}
|
||||
scale_value_x: 1 if root.icon else 0
|
||||
scale_value_y: 1 if root.icon else 0
|
||||
x: label_text.x - dp(32)
|
||||
|
||||
MDLabel:
|
||||
id: label_text
|
||||
text: root.text
|
||||
adaptive_size: True
|
||||
pos_hint: {"center_y": .5}
|
||||
x:
|
||||
root.center_x - (self.texture_size[0] / 2) \
|
||||
+ (dp(16) if root.icon else 0)
|
|
@ -0,0 +1,653 @@
|
|||
"""
|
||||
Components/SegmentedButton
|
||||
==========================
|
||||
|
||||
.. versionadded:: 1.2.0
|
||||
|
||||
.. seealso::
|
||||
|
||||
`Material Design spec, Segmented buttons <https://m3.material.io/components/segmented-buttons/overview>`_
|
||||
|
||||
`Segmented control <https://kivymd.readthedocs.io/en/latest/components/segmentedcontrol/>`_
|
||||
|
||||
.. rubric:: Segmented buttons help people select options, switch views,
|
||||
or sort elements.
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-preview.png
|
||||
:align: center
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
MDScreen:
|
||||
|
||||
MDSegmentedButton:
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
icon: ...
|
||||
text: ...
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
icon: ...
|
||||
text: ...
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
icon: ...
|
||||
text: ...
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from kivy.lang import Builder
|
||||
|
||||
from kivymd.app import MDApp
|
||||
|
||||
KV = '''
|
||||
MDScreen:
|
||||
|
||||
MDSegmentedButton:
|
||||
pos_hint: {"center_x": .5, "center_y": .5}
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Walking"
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Transit"
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Driving"
|
||||
'''
|
||||
|
||||
|
||||
class Example(MDApp):
|
||||
def build(self):
|
||||
self.theme_cls.theme_style = "Dark"
|
||||
return Builder.load_string(KV)
|
||||
|
||||
|
||||
Example().run()
|
||||
|
||||
By default, segmented buttons support single marking of elements:
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-multiselect-false.gif
|
||||
:align: center
|
||||
|
||||
For multiple marking of elements, use the
|
||||
:attr:`kivymd.uix.segmentedbutton.segmentedbutton.MDSegmentedButton.multiselect`
|
||||
parameter:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
MDSegmentedButton:
|
||||
multiselect: True
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-multiselect-true.gif
|
||||
:align: center
|
||||
|
||||
Control width
|
||||
-------------
|
||||
|
||||
The width of the panel of segmented buttons will be equal to the width
|
||||
of the texture of the widest button multiplied by the number of buttons:
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-width-by-default.png
|
||||
:align: center
|
||||
|
||||
But you can use the `size_hint_x` parameter to specify the relative width:
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
MDSegmentedButton:
|
||||
size_hint_x: .9
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-width-size-hint-x.png
|
||||
:align: center
|
||||
|
||||
Customization
|
||||
-------------
|
||||
|
||||
You can see below in the documentation from which classes the
|
||||
:class:`~kivymd.uix.segmentedbutton.segmentedbutton.MDSegmentedButton` and
|
||||
:class:`~kivymd.uix.segmentedbutton.segmentedbutton.MDSegmentedButtonItem`
|
||||
classes are inherited and use all their attributes such as
|
||||
`md_bg_color`, `md_bg_color` etc. for additional customization of segments.
|
||||
|
||||
Events
|
||||
------
|
||||
|
||||
- on_marked
|
||||
The method is called when a segment is marked.
|
||||
|
||||
- on_unmarked
|
||||
The method is called when a segment is unmarked.
|
||||
|
||||
.. code-block:: kv
|
||||
|
||||
MDSegmentedButton:
|
||||
on_marked: app.on_marked(*args)
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def on_marked(
|
||||
self,
|
||||
segment_button: MDSegmentedButton,
|
||||
segment_item: MDSegmentedButtonItem,
|
||||
marked: bool,
|
||||
) -> None:
|
||||
print(segment_button)
|
||||
print(segment_item)
|
||||
print(marked)
|
||||
|
||||
A practical example
|
||||
-------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import os
|
||||
|
||||
from faker import Faker
|
||||
|
||||
from kivy.clock import Clock
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import StringProperty
|
||||
|
||||
from kivymd.app import MDApp
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.segmentedbutton import MDSegmentedButton, MDSegmentedButtonItem
|
||||
from kivymd.utils import asynckivy
|
||||
|
||||
KV = '''
|
||||
<UserCard>
|
||||
adaptive_height: True
|
||||
md_bg_color: "#343930"
|
||||
radius: 16
|
||||
|
||||
TwoLineAvatarListItem:
|
||||
id: item
|
||||
divider: None
|
||||
_no_ripple_effect: True
|
||||
text: root.name
|
||||
secondary_text: root.path_to_file
|
||||
theme_text_color: "Custom"
|
||||
text_color: "#8A8D79"
|
||||
secondary_theme_text_color: self.theme_text_color
|
||||
secondary_text_color: self.text_color
|
||||
on_size:
|
||||
self.ids._left_container.size = (item.height, item.height)
|
||||
self.ids._left_container.x = dp(6)
|
||||
self._txt_right_pad = item.height + dp(12)
|
||||
|
||||
ImageLeftWidget:
|
||||
source: root.album
|
||||
radius: root.radius
|
||||
|
||||
|
||||
MDScreen:
|
||||
md_bg_color: "#151514"
|
||||
|
||||
MDBoxLayout:
|
||||
orientation: "vertical"
|
||||
padding: "12dp"
|
||||
spacing: "12dp"
|
||||
|
||||
MDLabel:
|
||||
adaptive_height: True
|
||||
text: "Your downloads"
|
||||
font_style: "H5"
|
||||
theme_text_color: "Custom"
|
||||
text_color: "#8A8D79"
|
||||
|
||||
MDSegmentedButton:
|
||||
size_hint_x: 1
|
||||
selected_color: "#303A29"
|
||||
line_color: "#343930"
|
||||
on_marked: app.on_marked(*args)
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Songs"
|
||||
active: True
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Albums"
|
||||
|
||||
MDSegmentedButtonItem:
|
||||
text: "Podcasts"
|
||||
|
||||
RecycleView:
|
||||
id: card_list
|
||||
viewclass: "UserCard"
|
||||
bar_width: 0
|
||||
|
||||
RecycleBoxLayout:
|
||||
orientation: 'vertical'
|
||||
spacing: "16dp"
|
||||
padding: "16dp"
|
||||
default_size: None, dp(72)
|
||||
default_size_hint: 1, None
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
'''
|
||||
|
||||
|
||||
class UserCard(MDBoxLayout):
|
||||
name = StringProperty()
|
||||
path_to_file = StringProperty()
|
||||
album = StringProperty()
|
||||
|
||||
|
||||
class Example(MDApp):
|
||||
def build(self):
|
||||
self.theme_cls.theme_style = "Dark"
|
||||
return Builder.load_string(KV)
|
||||
|
||||
def on_marked(
|
||||
self,
|
||||
segment_button: MDSegmentedButton,
|
||||
segment_item: MDSegmentedButtonItem,
|
||||
marked: bool,
|
||||
) -> None:
|
||||
self.generate_card()
|
||||
|
||||
def generate_card(self):
|
||||
async def generate_card():
|
||||
for i in range(10):
|
||||
await asynckivy.sleep(0)
|
||||
self.root.ids.card_list.data.append(
|
||||
{
|
||||
"name": fake.name(),
|
||||
"path_to_file": f"{os.path.splitext(fake.file_path())[0]}.mp3",
|
||||
"album": fake.image_url(),
|
||||
}
|
||||
)
|
||||
|
||||
fake = Faker()
|
||||
self.root.ids.card_list.data = []
|
||||
Clock.schedule_once(lambda x: asynckivy.start(generate_card()))
|
||||
|
||||
|
||||
Example().run()
|
||||
|
||||
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/segmented-button-practical-example.gif
|
||||
:align: center
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ("MDSegmentedButton", "MDSegmentedButtonItem")
|
||||
|
||||
import os
|
||||
|
||||
from kivy.animation import Animation
|
||||
from kivy.clock import Clock
|
||||
from kivy.lang import Builder
|
||||
from kivy.metrics import dp
|
||||
from kivy.properties import (
|
||||
BooleanProperty,
|
||||
ColorProperty,
|
||||
ListProperty,
|
||||
NumericProperty,
|
||||
StringProperty,
|
||||
VariableListProperty,
|
||||
)
|
||||
from kivy.uix.behaviors import ButtonBehavior
|
||||
|
||||
from kivymd import uix_path
|
||||
from kivymd.uix.behaviors import RectangularRippleBehavior, ScaleBehavior
|
||||
from kivymd.uix.boxlayout import MDBoxLayout
|
||||
from kivymd.uix.floatlayout import MDFloatLayout
|
||||
from kivymd.uix.label import MDIcon
|
||||
|
||||
with open(
|
||||
os.path.join(uix_path, "segmentedbutton", "segmentedbutton.kv"),
|
||||
encoding="utf-8",
|
||||
) as kv_file:
|
||||
Builder.load_string(kv_file.read())
|
||||
|
||||
|
||||
class MDSegmentedButtonItem(
|
||||
RectangularRippleBehavior, ButtonBehavior, MDFloatLayout
|
||||
):
|
||||
"""
|
||||
Segment button item.
|
||||
|
||||
For more information, see in the
|
||||
:class:`~kivymd.uix.behaviors.RectangularRippleBehavior` and
|
||||
:class:`~kivy.uix.behaviors.ButtonBehavior` and
|
||||
:class:`~kivymd.uix.boxlayout.MDBoxLayout`
|
||||
class documentation.
|
||||
"""
|
||||
|
||||
icon = StringProperty()
|
||||
"""
|
||||
Icon segment.
|
||||
|
||||
:attr:`icon` is an :class:`~kivy.properties.StringProperty`
|
||||
and defaults to `''`.
|
||||
"""
|
||||
|
||||
text = StringProperty()
|
||||
"""
|
||||
Text segment.
|
||||
|
||||
:attr:`text` is an :class:`~kivy.properties.StringProperty`
|
||||
and defaults to `''`.
|
||||
"""
|
||||
|
||||
active = BooleanProperty(False)
|
||||
"""
|
||||
Background color of an disabled segment.
|
||||
|
||||
:attr:`active` is an :class:`~kivy.properties.BooleanProperty`
|
||||
and defaults to `False`.
|
||||
"""
|
||||
|
||||
disabled_color = ColorProperty(None)
|
||||
"""
|
||||
Is active segment.
|
||||
|
||||
:attr:`active` is an :class:`~kivy.properties.ColorProperty`
|
||||
and defaults to `None`.
|
||||
"""
|
||||
|
||||
_no_ripple_effect = BooleanProperty(True)
|
||||
_current_icon = ""
|
||||
_current_md_bg_color = None
|
||||
|
||||
def on_disabled(self, instance, value: bool) -> None:
|
||||
def on_disabled(*args):
|
||||
if value:
|
||||
if not self._current_md_bg_color:
|
||||
self._current_md_bg_color = self.md_bg_color
|
||||
self.md_bg_color = (
|
||||
self.theme_cls.disabled_hint_text_color
|
||||
if not self.disabled_color
|
||||
else self.disabled_color
|
||||
)
|
||||
else:
|
||||
if self._current_md_bg_color:
|
||||
self.md_bg_color = self._current_md_bg_color
|
||||
self._current_md_bg_color = None
|
||||
|
||||
Clock.schedule_once(on_disabled)
|
||||
|
||||
def on_icon(self, instance, icon_name: str):
|
||||
if icon_name != "check":
|
||||
self._current_icon = icon_name
|
||||
|
||||
|
||||
# TODO:
|
||||
# Add the feature to use both text and icons in segments -
|
||||
# https://m3.material.io/components/segmented-buttons/guidelines#26abac1c-c6bd-44c1-a969-8c910c880b98
|
||||
# Icons: optional check icon to indicate selected state -
|
||||
# https://m3.material.io/components/segmented-buttons/overview#7b80f313-7d3a-4865-b26c-1f7ec98ba694
|
||||
# Hovered: add a color for the hovered segment -
|
||||
# https://m3.material.io/components/segmented-buttons/specs#d730b3ba-c59e-4ef8-b652-20979fe20b67
|
||||
# Density: Each step down in density removes 4dp from the height -
|
||||
# https://m3.material.io/components/segmented-buttons/specs#2d5cab36-1deb-40bd-9e37-bc2bb1657009
|
||||
|
||||
|
||||
class MDSegmentedButton(MDBoxLayout):
|
||||
"""
|
||||
Segment button panel.
|
||||
|
||||
For more information, see in the
|
||||
:class:`~kivymd.uix.boxlayout.MDBoxLayout` class documentation.
|
||||
|
||||
:Events:
|
||||
`on_marked`
|
||||
The method is called when a segment is marked.
|
||||
`on_unmarked`
|
||||
The method is called when a segment is unmarked.
|
||||
"""
|
||||
|
||||
radius = VariableListProperty([20], length=4)
|
||||
"""
|
||||
Panel radius.
|
||||
|
||||
:attr:`radius` is an :class:`~kivy.properties.VariableListProperty`
|
||||
and defaults to `[20, 20, 20, 20]`.
|
||||
"""
|
||||
|
||||
multiselect = BooleanProperty(False)
|
||||
"""
|
||||
Do I allow multiple segment selection.
|
||||
|
||||
:attr:`multiselect` is an :class:`~kivy.properties.BooleanProperty`
|
||||
and defaults to `False`.
|
||||
"""
|
||||
|
||||
hiding_icon_transition = StringProperty("linear")
|
||||
"""
|
||||
Name of the transition hiding the current icon.
|
||||
|
||||
:attr:`hiding_icon_transition` is a :class:`~kivy.properties.StringProperty`
|
||||
and defaults to `'linear'`.
|
||||
"""
|
||||
|
||||
hiding_icon_duration = NumericProperty(0.05)
|
||||
"""
|
||||
Duration of hiding the current icon.
|
||||
|
||||
:attr:`hiding_icon_duration` is a :class:`~kivy.properties.NumericProperty`
|
||||
and defaults to `0.05`.
|
||||
"""
|
||||
|
||||
opening_icon_transition = StringProperty("linear")
|
||||
"""
|
||||
The name of the transition that opens a new icon of the "marked" type.
|
||||
|
||||
:attr:`opening_icon_transition` is a :class:`~kivy.properties.StringProperty`
|
||||
and defaults to `'linear'`.
|
||||
"""
|
||||
|
||||
opening_icon_duration = NumericProperty(0.05)
|
||||
"""
|
||||
The duration of opening a new icon of the "marked" type.
|
||||
|
||||
:attr:`opening_icon_duration` is a :class:`~kivy.properties.NumericProperty`
|
||||
and defaults to `0.05`.
|
||||
"""
|
||||
|
||||
selected_items = ListProperty()
|
||||
"""
|
||||
The list of :class:`~MDSegmentedButtonItem` objects that are currently
|
||||
marked.
|
||||
|
||||
:attr:`selected_items` is a :class:`~kivy.properties.ListProperty`
|
||||
and defaults to `[]`.
|
||||
"""
|
||||
|
||||
selected_color = ColorProperty(None)
|
||||
"""
|
||||
Color of the marked segment.
|
||||
|
||||
:attr:`selected_color` is a :class:`~kivy.properties.ColorProperty`
|
||||
and defaults to `None`.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.register_event_type("on_marked")
|
||||
self.register_event_type("on_unmarked")
|
||||
Clock.schedule_once(self.mark_segment)
|
||||
Clock.schedule_once(self.adjust_segment_radius)
|
||||
Clock.schedule_once(self.adjust_segment_panel_width, 2)
|
||||
|
||||
def mark_segment(self, *args) -> None:
|
||||
"""Programmatically marks a segment."""
|
||||
|
||||
for widget in self.children:
|
||||
if widget.active:
|
||||
widget.active = False
|
||||
widget.dispatch("on_release")
|
||||
|
||||
if not self.multiselect:
|
||||
break
|
||||
|
||||
def adjust_segment_radius(self, *args) -> None:
|
||||
"""Rounds off the first and last elements."""
|
||||
|
||||
if self.children[0].radius == [0, 0, 0, 0]:
|
||||
self.children[0].radius = (0, self.height / 2, self.height / 2, 0)
|
||||
if self.children[-1].radius == [0, 0, 0, 0]:
|
||||
self.children[-1].radius = (self.height / 2, 0, 0, self.height / 2)
|
||||
|
||||
def adjust_segment_panel_width(self, *args) -> None:
|
||||
"""
|
||||
Sets the width of all segments and the width of the panel
|
||||
by the widest segment.
|
||||
"""
|
||||
|
||||
if not self.size_hint_x:
|
||||
width_list = [
|
||||
widget.ids.label_text.texture_size[0]
|
||||
+ (dp(72) if widget.icon else dp(48))
|
||||
for widget in self.children
|
||||
]
|
||||
max_width = max(width_list)
|
||||
self.width = max_width * len(width_list)
|
||||
else:
|
||||
max_width = self.width / len(self.children)
|
||||
|
||||
for widget in self.children:
|
||||
widget.width = max_width
|
||||
|
||||
self.opacity = 1
|
||||
|
||||
for widget in self.children:
|
||||
if widget.active:
|
||||
widget.dispatch("on_release")
|
||||
|
||||
def shift_segment_text(self, segment_item: MDSegmentedButtonItem) -> None:
|
||||
"""
|
||||
Shifts the segment text to the right, thus freeing up space
|
||||
for the icon (when the segment is marked).
|
||||
"""
|
||||
|
||||
Animation(
|
||||
x=(
|
||||
segment_item.ids.label_text.x
|
||||
+ (
|
||||
dp(16)
|
||||
if not segment_item.icon and not segment_item.active
|
||||
else 0
|
||||
)
|
||||
)
|
||||
if not segment_item.active
|
||||
else (
|
||||
segment_item.ids.label_text.x
|
||||
- (
|
||||
dp(16)
|
||||
if not segment_item.icon and segment_item.active
|
||||
else 0
|
||||
)
|
||||
),
|
||||
d=0.2,
|
||||
).start(segment_item.ids.label_text)
|
||||
|
||||
def show_icon_marked_segment(
|
||||
self, segment_item: MDSegmentedButtonItem
|
||||
) -> None:
|
||||
"""
|
||||
Sets the icon for the marked segment and changes the icon scale
|
||||
to the normal scale.
|
||||
"""
|
||||
|
||||
segment_item.ids.scale_icon.icon = "check"
|
||||
if segment_item.ids.scale_icon.icon == "check" and segment_item.active:
|
||||
segment_item.ids.scale_icon.icon = segment_item._current_icon
|
||||
|
||||
Animation(
|
||||
scale_value_x=1,
|
||||
scale_value_y=1,
|
||||
d=self.opening_icon_duration,
|
||||
t=self.opening_icon_transition,
|
||||
).start(segment_item.ids.scale_icon)
|
||||
|
||||
self.shift_segment_text(segment_item)
|
||||
self.set_selected_segment_list(segment_item)
|
||||
self.set_bg_marked_segment(segment_item)
|
||||
|
||||
def hide_icon_marked_segment(
|
||||
self, segment_item: MDSegmentedButtonItem
|
||||
) -> None:
|
||||
"""Changes the scale of the icon of the marked segment to zero."""
|
||||
|
||||
anim = Animation(
|
||||
scale_value_x=0,
|
||||
scale_value_y=0,
|
||||
d=self.hiding_icon_duration,
|
||||
t=self.hiding_icon_transition,
|
||||
)
|
||||
anim.bind(
|
||||
on_complete=lambda x, y: self.show_icon_marked_segment(segment_item)
|
||||
)
|
||||
anim.start(segment_item.ids.scale_icon)
|
||||
|
||||
def restore_bg_segment(self, segment_item) -> None:
|
||||
Animation(md_bg_color=self.md_bg_color, d=0.2).start(segment_item)
|
||||
|
||||
def set_bg_marked_segment(self, segment_item) -> None:
|
||||
if segment_item.active:
|
||||
Animation(
|
||||
md_bg_color=self.selected_color
|
||||
if self.selected_color
|
||||
else self.theme_cls.primary_color,
|
||||
d=0.2,
|
||||
).start(segment_item)
|
||||
|
||||
def set_selected_segment_list(self, segment_item) -> None:
|
||||
segment_item.active = not segment_item.active
|
||||
|
||||
if segment_item.active:
|
||||
self.selected_items.append(segment_item)
|
||||
self.dispatch("on_marked", segment_item, segment_item.active)
|
||||
else:
|
||||
if segment_item in self.selected_items:
|
||||
self.selected_items.remove(segment_item)
|
||||
self.dispatch("on_unmarked", segment_item, segment_item.active)
|
||||
|
||||
def mark_item(self, segment_item: MDSegmentedButtonItem) -> None:
|
||||
if segment_item.active and not self.multiselect:
|
||||
return
|
||||
if not self.multiselect and self.selected_items:
|
||||
self.uncheck_item()
|
||||
else:
|
||||
if segment_item.active:
|
||||
self.restore_bg_segment(segment_item)
|
||||
|
||||
self.hide_icon_marked_segment(segment_item)
|
||||
|
||||
def uncheck_item(self) -> None:
|
||||
for item in self.children:
|
||||
if item.active:
|
||||
self.hide_icon_marked_segment(item)
|
||||
self.restore_bg_segment(item)
|
||||
break
|
||||
|
||||
def add_widget(self, widget, *args, **kwargs):
|
||||
if isinstance(widget, MDSegmentedButtonItem):
|
||||
widget.bind(on_release=self.mark_item)
|
||||
return super().add_widget(widget)
|
||||
|
||||
def on_size(self, instance_segment_button, size: list) -> None:
|
||||
"""Called when the root screen is resized."""
|
||||
|
||||
if self.size_hint_x:
|
||||
max_width = size[0] / len(self.children)
|
||||
for widget in self.children:
|
||||
widget.width = max_width
|
||||
|
||||
def on_marked(self, *args):
|
||||
"""The method is called when a segment is marked."""
|
||||
|
||||
def on_unmarked(self, *args):
|
||||
"""The method is called when a segment is unmarked."""
|
||||
|
||||
|
||||
class SegmentButtonIcon(MDIcon, ScaleBehavior):
|
||||
"""Implements an icon with scaling behavior."""
|
Loading…
Add table
Add a link
Reference in a new issue