diff --git a/docs/release_notes/next/feature-1992-ROI-colour b/docs/release_notes/next/feature-1992-ROI-colour new file mode 100644 index 00000000000..3de82d867b5 --- /dev/null +++ b/docs/release_notes/next/feature-1992-ROI-colour @@ -0,0 +1 @@ +#1992 : Spectrum Viewer: Change ROI Colour Through Right Click Dialog Menu diff --git a/mantidimaging/gui/windows/spectrum_viewer/presenter.py b/mantidimaging/gui/windows/spectrum_viewer/presenter.py index fc3518bf5bf..1e67adfdabc 100644 --- a/mantidimaging/gui/windows/spectrum_viewer/presenter.py +++ b/mantidimaging/gui/windows/spectrum_viewer/presenter.py @@ -225,6 +225,17 @@ def do_add_roi(self) -> None: self.view.auto_range_image() self.do_add_roi_to_table(roi_name) + def change_roi_colour(self, roi_name: str, new_colour: tuple) -> None: + """ + Change the colour of a given ROI in both the spectrum widget and the table. + + @param roi_name: Name of the ROI to change color. + @param new_colour: The new color for the ROI. + """ + if roi_name in self.view.spectrum_widget.roi_dict: + self.view.spectrum_widget.roi_dict[roi_name].colour = new_colour + self.view.update_roi_color_in_table(roi_name, new_colour) + def add_rits_roi(self) -> None: roi_name = ROI_RITS self.model.set_new_roi(roi_name) diff --git a/mantidimaging/gui/windows/spectrum_viewer/roi_table_model.py b/mantidimaging/gui/windows/spectrum_viewer/roi_table_model.py index abbb2dd5dc3..c4bc65e2ff8 100644 --- a/mantidimaging/gui/windows/spectrum_viewer/roi_table_model.py +++ b/mantidimaging/gui/windows/spectrum_viewer/roi_table_model.py @@ -61,6 +61,12 @@ def data(self, index, role): return Qt.Checked return Qt.Unchecked + def update_color(self, row, new_color): + if 0 <= row < len(self._data): + self._data[row][1] = new_color + index = self.index(row, 1) + self.dataChanged.emit(index, index, [Qt.DisplayRole, Qt.BackgroundRole]) + def setData(self, index, value, role): """ Set data in table diff --git a/mantidimaging/gui/windows/spectrum_viewer/spectrum_widget.py b/mantidimaging/gui/windows/spectrum_viewer/spectrum_widget.py index 79cf0196db6..86c94197d57 100644 --- a/mantidimaging/gui/windows/spectrum_viewer/spectrum_widget.py +++ b/mantidimaging/gui/windows/spectrum_viewer/spectrum_widget.py @@ -5,7 +5,8 @@ from typing import TYPE_CHECKING, Optional from PyQt5.QtCore import pyqtSignal, Qt, QSignalBlocker -from PyQt5.QtWidgets import QSplitter, QWidget, QVBoxLayout +from PyQt5.QtGui import QColor +from PyQt5.QtWidgets import QColorDialog, QAction, QMenu, QSplitter, QWidget, QVBoxLayout from pyqtgraph import ROI, GraphicsLayoutWidget, LinearRegionItem, PlotItem, mkPen from mantidimaging.core.utility.close_enough_point import CloseEnoughPoint @@ -25,6 +26,7 @@ class SpectrumROI(ROI): @param args: Arguments to pass to the ROI object @param kwargs: Keyword arguments to pass to the ROI object """ + sig_colour_change = pyqtSignal(str, tuple) def __init__(self, name: str, sensible_roi: SensibleROI, *args, **kwargs): super().__init__(*args, **kwargs) @@ -39,6 +41,22 @@ def __init__(self, name: str, sensible_roi: SensibleROI, *args, **kwargs): self.addScaleHandle([0, 1], [1, 0]) self._selected_row = None + self.menu = QMenu() + change_color_action = QAction("Change ROI Colour", self) + change_color_action.triggered.connect(self.onChangeColor) + self.menu.addAction(change_color_action) + + def onChangeColor(self): + current_color = QColor(*self._colour) + selected_color = QColorDialog.getColor(current_color) + if selected_color.isValid(): + new_color = (selected_color.red(), selected_color.green(), selected_color.blue(), 255) + self._colour = new_color + self.sig_colour_change.emit(self._name, new_color) + + def contextMenuEnabled(self): + return True + @property def name(self) -> str: return self._name @@ -74,6 +92,8 @@ class SpectrumWidget(QWidget): image: MIMiniImageView spectrum: PlotItem roi_changed = pyqtSignal() + roiColorChangeRequested = pyqtSignal(str, tuple) + spectrum_plot_widget: SpectrumPlotWidget image_widget: SpectrumProjectionWidget @@ -150,6 +170,7 @@ def set_roi_alpha(self, name: str, alpha: float) -> None: @param name: The name of the ROI. @param alpha: The new alpha value of the ROI. """ + self.roi_dict[name].colour = self.roi_dict[name].colour[:3] + (alpha, ) self.roi_dict[name].setPen(self.roi_dict[name].colour) self.roi_dict[name].hoverPen = mkPen(self.roi_dict[name].colour, width=3) @@ -164,6 +185,7 @@ def add_roi(self, roi: SensibleROI, name: str) -> None: """ roi_object = SpectrumROI(name, roi, pos=(0, 0), rotatable=False, scaleSnap=True, translateSnap=True) roi_object.colour = self.colour_generator() + roi_object.sig_colour_change.connect(lambda name, color: self.roiColorChangeRequested.emit(name, color)) self.roi_dict[name] = roi_object.roi self.max_roi_size = roi_object.size() diff --git a/mantidimaging/gui/windows/spectrum_viewer/view.py b/mantidimaging/gui/windows/spectrum_viewer/view.py index a71d08a658c..38447d29779 100644 --- a/mantidimaging/gui/windows/spectrum_viewer/view.py +++ b/mantidimaging/gui/windows/spectrum_viewer/view.py @@ -65,6 +65,7 @@ def __init__(self, main_window: 'MainWindowView'): self.spectrum.range_changed.connect(self.presenter.handle_range_slide_moved) self.spectrum_widget.roi_changed.connect(self.presenter.handle_roi_moved) + self.spectrum_widget.roiColorChangeRequested.connect(self.presenter.change_roi_colour) self._current_dataset_id = None self.sampleStackSelector.stack_selected_uuid.connect(self.presenter.handle_sample_change) @@ -266,6 +267,29 @@ def set_new_roi(self) -> None: """ self.presenter.do_add_roi() + def update_roi_color_in_table(self, roi_name: str, new_color: tuple): + """ + Finds ROI by name in table and updates colour. + + @param roi_name: Name of the ROI to update. + @param new_color: The new color for the ROI in (R, G, B) format. + """ + row = self.find_row_for_roi(roi_name) + if row is not None: + self.roi_table_model.update_color(row, new_color) + + def find_row_for_roi(self, roi_name: str) -> Optional[int]: + """ + Returns row index for ROI name, or None if not found. + + @param roi_name: Name ROI find. + @return: Row index ROI or None. + """ + for row in range(self.roi_table_model.rowCount()): + if self.roi_table_model.index(row, 0).data() == roi_name: + return row + return None + def set_roi_alpha(self, alpha: float, roi_name: str) -> None: """ Set the alpha value for the selected ROI and update the spectrum to reflect the change. @@ -293,8 +317,6 @@ def add_roi_table_row(self, name: str, colour: tuple[int, int, int]): @param name: The name of the ROI @param colour: The colour of the ROI """ - circle_label = QLabel() - circle_label.setStyleSheet(f"background-color: {colour}; border-radius: 5px;") self.roi_table_model.appendNewRow(name, colour, True) self.selected_row = self.roi_table_model.rowCount() - 1 self.tableView.selectRow(self.selected_row)