Repository: napari/napari

Issue:
Brush size caps at 40 when changing it via code but does not cap the same way when trying to set it via  ipython console
## 🐛 Bug
I have the below code in one of my programs when I run that the brush size is printed out as 40 which makes sense as https://github.com/napari/napari/blob/master/napari/_qt/layer_controls/qt_labels_controls.py#L415
but I would want the brush size to go over 40 pixels, so I tried to change it once the window opened with images. So, I set the brush_size with the same command in the ipython console generated using ``viewer.layers["binary"].brush_size =100`` it sets to 100. So, I am not sure why it isn't clipping once but it is clipping the other time, maybe the event is being generated vs not.

```
        viewer.layers["binary"].mode = "paint"
        viewer.layers["binary"].brush_size = int(100.0)
        viewer.layers["binary"].brush_shape = "circle"
        print("updated binary brush size")
````

<!-- If you have a code sample, error messages, stack traces, please provide it here as well -->

## Expected behavior

1. I wanted to see if brush_size range could be set by the user instead of clipping it at 40 
2. I wanted to also find out why the events are inconsistently generated

## Environment

 - Please copy and paste the information at napari info option in help menubar here:

 - Any other relevant information:

## Additional context

<!-- Add any other context about the problem here. -->



Discussion:
Ah yeah this relates to how we're currently doing our sliders and if an event triggers the slider which then does the clip. We might want to think of updating the max allowed value of the slider rather than clipping. Curious what others think?
 Wondering if anyone else has any input on this?
@pranathivemuri there is some work going on in #2709 and #2753 that will allow more flexibility over our sliders. Once we've got those in we should be able to make this change more easily
thanks! :)
@pranathivemuri if you comment out the clipping and instead update the max allowed value do things now work for you? We could just merge that without waiting on #2753 to be done 

https://github.com/napari/napari/blob/ed6b8ef2e55471b42a3ea47875b7e1ef0f99ba80/napari/_qt/layer_controls/qt_labels_controls.py#L434

Resolving patch:
diff --git a/napari/_qt/layer_controls/qt_labels_controls.py b/napari/_qt/layer_controls/qt_labels_controls.py
--- a/napari/_qt/layer_controls/qt_labels_controls.py
+++ b/napari/_qt/layer_controls/qt_labels_controls.py
@@ -431,7 +431,9 @@ def _on_brush_size_change(self, event=None):
         """
         with self.layer.events.brush_size.blocker():
             value = self.layer.brush_size
-            value = np.clip(int(value), 1, 40)
+            value = np.maximum(1, int(value))
+            if value > self.brushSizeSlider.maximum():
+                self.brushSizeSlider.setMaximum(int(value))
             self.brushSizeSlider.setValue(value)
 
     def _on_n_edit_dimensions_change(self, event=None):


Test patch:
diff --git a/napari/_tests/test_advanced.py b/napari/_tests/test_advanced.py
--- a/napari/_tests/test_advanced.py
+++ b/napari/_tests/test_advanced.py
@@ -259,3 +259,19 @@ def test_labels_undo_redo(make_napari_viewer):
     # cannot undo as limit exceeded
     labels.undo()
     assert np.array_equal(l2, labels.data)
+
+
+def test_labels_brush_size(make_napari_viewer):
+    """Test changing labels brush size."""
+    viewer = make_napari_viewer()
+
+    data = np.zeros((50, 50), dtype=np.uint8)
+    labels = viewer.add_labels(data)
+
+    # Make small change
+    labels.brush_size = 20
+    assert labels.brush_size == 20
+
+    # Make large change
+    labels.brush_size = 100
+    assert labels.brush_size == 100