/
material_progress.py
117 lines (90 loc) · 4.11 KB
/
material_progress.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""This module contains the Material LinearProgress and CircularProgress"""
import param
from awesome_panel_extensions.frameworks._base.progress import Progress as _BaseProgress
_ATTRIBUTES_TO_WATCH_BASE = {"class": "bar_color"}
_PROPERTIES_TO_WATCH_BASE = {
"indeterminate": "active",
"progress": "_progress",
"closed": "closed",
}
DENSITY_RATIO = 4
class _MaterialProgress(_BaseProgress):
closed = param.Boolean(
default=False,
doc="""Sets the progress indicator to the closed state. Sets content opacity to 0.
Typically should be set to true when loading has finished.""",
)
_progress = param.Number(default=None, bounds=(0, 1), allow_None=True)
attributes_to_watch = param.Dict(_ATTRIBUTES_TO_WATCH_BASE)
properties_to_watch = param.Dict(_PROPERTIES_TO_WATCH_BASE)
def __init__(self, **params):
# Hack: to make sure that value is shown on construction
if "value" in params and "active" not in params:
params["active"] = False
super().__init__(**params)
self._update_progress()
@param.depends("value", "max", watch=True)
def _update_progress(self, *_):
if self.value is None or self.value == 0 or self.max is None or self.max == 0:
self._progress = None
else:
self._progress = self.value / self.max
class LinearProgress(_MaterialProgress):
"""The Material LinearProgress widget conveys progress information to the user"""
html = param.String(
"<mwc-linear-progress style='width:100%' progress='0.0'></mwc-linear-progress"
)
buffer = param.Integer(
default=None,
bounds=(0, 100),
allow_None=True,
doc="""Sets the buffer progress bar's value. Value should be between [0, 1].
Setting this value to be less than max will reveal moving, buffering dots.""",
)
_buffer = param.Number(default=None, allow_None=True,)
reverse = param.Boolean(
default=False, doc="Reverses the direction of the linear progress indicator."
)
properties_to_watch = param.Dict(
{**_PROPERTIES_TO_WATCH_BASE, "buffer": "_buffer", "reverse": "reverse"}
)
@param.depends("max", watch=True)
def _update_buffer_bounds(self):
self.param.buffer.bounds = (0, self.max)
@param.depends("buffer", "max", watch=True)
def _update_buffer(self, *_):
if self.buffer is None or self.buffer == 0 or self.max is None or self.max == 0:
self._buffer = None
else:
self._buffer = self.buffer / self.max
class CircularProgress(_MaterialProgress):
"""The Material Circular Progress Widget conveys progress information to the user"""
html = param.String("<mwc-circular-progress style='width:51px'></mwc-circular-progress")
density = param.Integer(
default=0,
bounds=(-8, 2000),
doc="""Sets the progress indicator's sizing based on density scale. Minimum value is -8.
Each unit change in density scale corresponds to 4px change in side dimensions. The stroke
width adjusts automatically.""",
)
# _style = param.String()
# attributes_to_watch = param.Dict(dict(**_ATTRIBUTES_TO_WATCH_BASE, style="_style"))
properties_to_watch = param.Dict(dict(**_PROPERTIES_TO_WATCH_BASE, density="density"))
def __init__(self, **params):
if "density" in params and "html" not in params:
density = params["density"]
diameter = round((density + 8) * DENSITY_RATIO + 17)
html = (
f"<mwc-circular-progress style='height:{diameter}px;width:{diameter}px' "
f"density={density}></mwc-circular-progress"
)
params["html"] = html
super().__init__(**params)
self._update_diameter()
@param.depends("density", watch=True)
def _update_diameter(self, *_):
diameter = round((self.density + 8) * DENSITY_RATIO + 17)
self.min_height = diameter
self.min_width = diameter
# Cannot get the style updating programmatically. Starts an infinite loop.
# self._style = f"height:{diameter}px;width:{diameter}px;"