class DistanceWidget(QWidget):
    """ Widget used to manually edit the selection radius"""

    distanceChanged = pyqtSignal(float)
    distanceEditingFinished = pyqtSignal(Qt.KeyboardModifiers)
    distanceEditingCanceled = pyqtSignal()

    def __init__(self, label, parent=None):
        super().__init__(parent)
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setAlignment(Qt.AlignLeft)

        if label:
            self.label = QLabel(label, self)
            self.label.setAlignment(Qt.AlignRight | Qt.AlignCenter)
            layout.addWidget(self.label)

        self.spinbox = QgsDoubleSpinBox(self)
        self.spinbox.setSingleStep(1)
        self.spinbox.setValue(0)
        self.spinbox.setMinimum(0)
        self.spinbox.setMaximum(1000000000)
        self.spinbox.setDecimals(6)
        self.spinbox.setShowClearButton(False)
        self.spinbox.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Preferred)
        layout.addWidget(self.spinbox)

        # connect signals
        self.spinbox.installEventFilter(self)
        self.spinbox.valueChanged.connect(self.distanceChanged.emit)

        # config focus
        self.setFocusProxy(self.spinbox)

    def set_distance(self, distance):
        """ set the selection radius """
        self.spinbox.setValue(distance)
        self.spinbox.selectAll()

    def distance(self):
        """ return he selection radius """
        return self.spinbox.value()

    def eventFilter(self, obj, event):
        """ Intercept key press event to emit our own custom signals """
        # pylint: disable=invalid-name

        if obj is self.spinbox and event.type() == QEvent.KeyPress:

            if event.key() == Qt.Key_Escape:

                self.distanceEditingCanceled.emit()
                return True

            if event.key() in (Qt.Key_Enter, Qt.Key_Return):
                # Emit the editing finished signal with modifier to handle remove
                # from selection and add to selection
                self.distanceEditingFinished.emit(event.modifiers())
                return True

        return False