class _AngleRangeWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Widgets
        self._txt_lower = MultiNumericalLineEdit()
        self._txt_upper = MultiNumericalLineEdit()
        self._cb_unit = AngleComboBox()
        self._cb_unit.setUnit(u'\u00b0')

        # Layouts
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._txt_lower, 1)
        layout.addWidget(QLabel("-"))
        layout.addWidget(self._txt_upper, 1)
        layout.addWidget(self._cb_unit)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        self._txt_lower.textChanged.connect(self.valuesChanged)
        self._txt_upper.textChanged.connect(self.valuesChanged)
        self._cb_unit.currentIndexChanged.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._txt_lower.setStyleSheet("background: none")
            self._txt_upper.setStyleSheet("background: none")
        else:
            self._txt_lower.setStyleSheet("background: pink")
            self._txt_upper.setStyleSheet("background: pink")

    def values(self):
        lows = self._txt_lower.values() * self._cb_unit.factor()
        ups = self._txt_upper.values() * self._cb_unit.factor()
        return list(product(lows, ups))

    def setValues(self, values):
        values = np.array(values, ndmin=1)
        self._txt_lower.setValues(list(map(np.degrees, map(itemgetter(0), values))))
        self._txt_upper.setValues(list(map(np.degrees, map(itemgetter(1), values))))
        self._cb_unit.setUnit(u'\u00b0')

    def isReadOnly(self):
        return self._txt_lower.isReadOnly() and \
            self._txt_upper.isReadOnly() and \
            not self._cb_unit.isEnabled()

    def setReadOnly(self, state):
        self._txt_lower.setReadOnly(state)
        self._txt_upper.setReadOnly(state)
        self._cb_unit.setEnabled(not state)
class AngleParameterWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Widgets
        self._cb_unit = AngleComboBox()
        self._cb_unit.setUnit(u'\u00b0')

        self._txt_values = MultiNumericalLineEdit()
        validator = _FactorParameterValidator(parameter, self._cb_unit)
        self._txt_values.setValidator(validator)

        # Layouts
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._txt_values, 1)
        layout.addWidget(self._cb_unit)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        self._txt_values.textChanged.connect(self.valuesChanged)
        self._cb_unit.currentIndexChanged.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._txt_values.setStyleSheet("background: none")
        else:
            self._txt_values.setStyleSheet("background: pink")

    def values(self):
        return self._txt_values.values() * self._cb_unit.factor()

    def setValues(self, values):
        self._txt_values.setValues(np.degrees(values))
        self._cb_unit.setUnit(u'\u00b0')

    def isReadOnly(self):
        return self._txt_values.isReadOnly() and not self._cb_unit.isEnabled()

    def setReadOnly(self, state):
        self._txt_values.setReadOnly(state)
        self._cb_unit.setEnabled(not state)

    def hasAcceptableInput(self):
        if not _ParameterWidget.hasAcceptableInput(self):
            return False
        return self._txt_values.hasAcceptableInput()