Repository: napari/napari

Issue:
Shapes color swatches not updating when selecting different points
## 🐛 Bug

As reported by @sofroniewn in #1374 , the color swatches in the points layer are not updating to reflect the currently selected points. I haven't had a chance to investigate, but I think this is likely just a missing event connection in the `Shapes` qt layer controls.

## To Reproduce

Steps to reproduce the behavior:

1. Run examples/add_shapes.py
2. Enter selection mode
3. Click different shapes
4. The colors in the layer controls should update to reflect the selected point, but they don't.


## Expected behavior

When a point is selected, the color swatches in the layer controls should update to match the colors of the selected point.

## Environment

napari: 0.3.5.dev14+g02d296b.d20200614
Platform: Darwin-18.7.0-x86_64-i386-64bit
Python: 3.7.7 (default, Mar 10 2020, 15:43:03) [Clang 11.0.0 (clang-1100.0.33.17)]
Qt: 5.14.1
PySide2: 5.14.1
NumPy: 1.18.1
SciPy: 1.4.1
Dask: 2.12.0
VisPy: 0.6.4

GL version: 2.1 INTEL-12.10.19
MAX_TEXTURE_SIZE: 16384

Plugins:
- napari-plugin-engine: 0.1.5
- napari-plugins: 0.1.0
- svg: 0.1.3

## Additional context

This can likely be fixed by copying the events and callback functions related to edge color from the [Points layer controls qt file](https://github.com/napari/napari/blob/master/napari/_qt/layers/qt_points_layer.py) to the [Shapes layer controls qt file](https://github.com/napari/napari/blob/master/napari/_qt/layers/qt_shapes_layer.py).



Discussion:
Looks like in `0.3.5` this was working for face color but not edge color. Same is true now - it looks like the fail is edge color swatch specific, face color changes fine. Seems like problem has always been there for edge color

Resolving patch:
diff --git a/napari/_qt/layers/qt_shapes_layer.py b/napari/_qt/layers/qt_shapes_layer.py
--- a/napari/_qt/layers/qt_shapes_layer.py
+++ b/napari/_qt/layers/qt_shapes_layer.py
@@ -294,18 +294,6 @@ def changeWidth(self, value):
         """
         self.layer.current_edge_width = float(value) / 2
 
-    def changeOpacity(self, value):
-        """Change opacity value of shapes on the layer model.
-
-        Parameters
-        ----------
-        value : float
-            Opacity value for shapes.
-            Input range 0 - 100 (transparent to fully opaque).
-        """
-        with self.layer.events.blocker(self._on_opacity_change):
-            self.layer.opacity = value / 100
-
     def _on_edge_width_change(self, event=None):
         """Receive layer model edge line width change event and update slider.
 
@@ -341,17 +329,6 @@ def _on_face_color_change(self, event=None):
         with qt_signals_blocked(self.faceColorEdit):
             self.faceColorEdit.setColor(self.layer.current_face_color)
 
-    def _on_opacity_change(self, event=None):
-        """Receive layer model opacity change event and update opacity slider.
-
-        Parameters
-        ----------
-        event : qtpy.QtCore.QEvent, optional.
-            Event from the Qt context, by default None.
-        """
-        with self.layer.events.opacity.blocker():
-            self.opacitySlider.setValue(self.layer.opacity * 100)
-
     def _on_editable_change(self, event=None):
         """Receive layer model editable change event & enable/disable buttons.
 
diff --git a/napari/layers/shapes/shapes.py b/napari/layers/shapes/shapes.py
--- a/napari/layers/shapes/shapes.py
+++ b/napari/layers/shapes/shapes.py
@@ -565,7 +565,7 @@ def current_edge_color(self, edge_color):
             for i in self.selected_data:
                 self._data_view.update_edge_color(i, self._current_edge_color)
         self.events.edge_color()
-        self.events.current_face_color()
+        self.events.current_edge_color()
 
     @property
     def current_face_color(self):


Test patch:
diff --git a/napari/_qt/layers/_tests/test_qt_shapes_layer.py b/napari/_qt/layers/_tests/test_qt_shapes_layer.py
new file mode 100644
--- /dev/null
+++ b/napari/_qt/layers/_tests/test_qt_shapes_layer.py
@@ -0,0 +1,35 @@
+import numpy as np
+from napari._qt.layers.qt_shapes_layer import QtShapesControls
+from napari.layers import Shapes
+from napari.utils.colormaps.standardize_color import transform_color
+
+
+_SHAPES = np.random.random((10, 4, 2))
+
+
+def test_shape_controls_face_color(qtbot):
+    """Check updating of face color updates QtShapesControls."""
+    layer = Shapes(_SHAPES)
+    qtctrl = QtShapesControls(layer)
+    qtbot.addWidget(qtctrl)
+    target_color = transform_color(layer.current_face_color)[0]
+    np.testing.assert_almost_equal(qtctrl.faceColorEdit.color, target_color)
+
+    # Update current face color
+    layer.current_face_color = 'red'
+    target_color = transform_color(layer.current_face_color)[0]
+    np.testing.assert_almost_equal(qtctrl.faceColorEdit.color, target_color)
+
+
+def test_shape_controls_edge_color(qtbot):
+    """Check updating of edge color updates QtShapesControls."""
+    layer = Shapes(_SHAPES)
+    qtctrl = QtShapesControls(layer)
+    qtbot.addWidget(qtctrl)
+    target_color = transform_color(layer.current_edge_color)[0]
+    np.testing.assert_almost_equal(qtctrl.edgeColorEdit.color, target_color)
+
+    # Update current edge color
+    layer.current_edge_color = 'red'
+    target_color = transform_color(layer.current_edge_color)[0]
+    np.testing.assert_almost_equal(qtctrl.edgeColorEdit.color, target_color)