Repository: holoviz/panel

Issue:
Better control over Progress Bar features
I was working on one dashboard where I had multiple scenarios I would wish to be communicated through single Progress bar.

Ultimately it would be great to use these two modes somehow:
https://www.w3schools.com/bootstrap/bootstrap_progressbars.asp
1.  Animated Progress Bar
2.  Stacked Progress Bar

It would be also great to switch programmatically between Stripped and Animated  progress bars - but it might be too much to ask...


Discussion:
Hi @thoth291 

Maybe you can get some inspiration on the progressbar from the example in the gallery at awesome-panel.org.

![image](https://user-images.githubusercontent.com/42288570/73392318-da897780-42d9-11ea-8984-73af220a1099.png)

There is a link to the code at the top of the page.

Thank you, @MarcSkovMadsen - but none of the examples show me how to implement what I'm actually looking for. BTW, I never heard about this site - thanks for pointing to it.
The ideas behind the progress reporting powering awesome-panel.org are

- A seperate "message queue" for progress that progress bars can subscribe to (param.depends). The message consists of a progress value and a progress message string. I have later learned that it would be nice to support multiple named queues. This would support having multiple progress bars reporting from one or more selected queues.
- An extended Progress Bar widget that can subscribe to the progress message queue and report both the value and the message. And handle situations where  one or the other is 0, None or "".
- The "message queue" comes with functionality for sending/ reporting absolute progress values and incremental progress values.
- The "message queue" comes with functionality for annotating functions (I.e. reporting progress while a function is running) and a context manager (I.e. reporting progress within a `with` statement).

You can check out the implementation

https://github.com/MarcSkovMadsen/awesome-panel/blob/master/package/awesome_panel/express/widgets/progress_ext.py

and the tests shown in the gallery at awesome-panel.org

https://github.com/MarcSkovMadsen/awesome-panel/blob/master/src/pages/gallery/awesome_panel_express_tests/test_progress_ext.py

and used in an app

https://github.com/MarcSkovMadsen/awesome-panel/blob/master/src/pages/gallery/yahooquery_app/yahooquery_app.py


If you think something like the above is usefull I could be motivated to contribute what I have and work together with someone on maturing and generalizing it.

Resolving patch:
diff --git a/panel/models/widgets.py b/panel/models/widgets.py
--- a/panel/models/widgets.py
+++ b/panel/models/widgets.py
@@ -123,7 +123,7 @@ class Progress(HTMLBox):
 
     max = Int(100, help="""Maximum value""")
 
-    value = Int(help="""Current value""")
+    value = Nullable(Int, help="""Current value""")
 
     style = Dict(String, Any, default={}, help="""
     Raw CSS style declaration. Note this may be web browser dependent.
diff --git a/panel/widgets/indicators.py b/panel/widgets/indicators.py
--- a/panel/widgets/indicators.py
+++ b/panel/widgets/indicators.py
@@ -1,5 +1,6 @@
 import os
 import sys
+import warnings
 
 from math import pi
 
@@ -130,10 +131,12 @@ class Progress(ValueIndicator):
 
     max = param.Integer(default=100, doc="The maximum value of the progress bar.")
 
-    value = param.Integer(default=None, bounds=(-1, None), doc="""
-        The current value of the progress bar. If set to None the progress
+    value = param.Integer(default=-1, bounds=(-1, None),                           
+                          allow_None = True,#TODO: remove
+                          doc="""
+        The current value of the progress bar. If set to -1 the progress
         bar will be indeterminate and animate depending on the active
-        parameter. If set to -1 the progress bar will be empty.""")
+        parameter.""")
 
     _rename = {'name': None}
 
@@ -142,6 +145,13 @@ class Progress(ValueIndicator):
     @param.depends('max', watch=True)
     def _update_value_bounds(self):
         self.param.value.bounds = (-1, self.max)
+        
+    @param.depends('value', watch=True)
+    def _warn_deprecation(self):
+        if self.value is None:
+            self.value = -1
+            warnings.warn('Setting the progress value to None is deprecated, use -1 instead.', 
+                          FutureWarning,  stacklevel=2)  
 
     def __init__(self,**params):
         super().__init__(**params)
@@ -722,9 +732,8 @@ class Tqdm(Indicator):
 
     layout = param.ClassSelector(class_=(Column, Row), precedence=-1, constant=True, doc="""
         The layout for the text and progress indicator.""",)
-
-    max = param.Integer(default=100, doc="""
-        The maximum value of the progress indicator.""")
+            
+    max = Progress.param.max
 
     progress = param.ClassSelector(class_=Progress, precedence=-1, doc="""
         The Progress indicator used to display the progress.""",)
@@ -734,11 +743,9 @@ class Tqdm(Indicator):
 
     text_pane = param.ClassSelector(class_=Str, precedence=-1, doc="""
         The pane to display the text to.""")
-
-    value = param.Integer(default=0, bounds=(0, None), doc="""
-        The current value of the progress bar. If set to None the progress
-        bar will be indeterminate and animate depending on the active
-        parameter.""")
+        
+    value = Progress.param.value
+    value.default = 0
 
     margin = param.Parameter(default=0, doc="""
         Allows to create additional space around the component. May
@@ -786,13 +793,8 @@ def __init__(self, **params):
 
         self.param.watch(self._update_layout, list(Viewable.param))
 
-        if self.value == 0:
-            # Hack: to give progress the initial look
-            self.progress.max = 100000
-            self.progress.value = 1
-        else:
-            self.progress.max = self.max
-            self.progress.value = self.value
+        self.progress.max = self.max
+        self.progress.value = self.value
         self.text_pane.object = self.text
 
     def _get_model(self, doc, root=None, parent=None, comm=None):


Test patch:
diff --git a/panel/tests/widgets/test_misc.py b/panel/tests/widgets/test_misc.py
--- a/panel/tests/widgets/test_misc.py
+++ b/panel/tests/widgets/test_misc.py
@@ -11,6 +11,8 @@ def test_progress_bounds():
     assert progress.param.value.bounds == (-1, 200)
     progress.value = 120
     assert progress.value == 120
+    progress.value = -1
+    assert progress.value == -1
 
 
 def test_file_download_label():