Example #1
0
class FlipRotateMixin(base.BaseTransformMixin):
    """Rotate & Crop mixin class, to be mixed with a class providing the 
    get_plot method, like ImageDialog or FlipRotateWidget (see below)"""
    ROTATION_ANGLES = [str((i - 1) * 90) for i in range(4)]

    #------BaseTransformMixin API----------------------------------------------
    def add_buttons_to_layout(self, layout):
        """Add tool buttons to layout"""
        # Image orientation
        angle_label = QLabel(_("Angle (°):"))
        layout.addWidget(angle_label)
        self.angle_combo = QComboBox(self)
        self.angle_combo.addItems(self.ROTATION_ANGLES)
        self.angle_combo.setCurrentIndex(1)
        self.angle_combo.currentIndexChanged.connect(
            lambda index: self.apply_transformation())
        layout.addWidget(self.angle_combo)
        layout.addSpacing(10)

        # Image flipping
        flip_label = QLabel(_("Flip:"))
        layout.addWidget(flip_label)
        hflip = create_toolbutton(
            self,
            text="",
            icon=get_icon("hflip.png"),
            toggled=lambda state: self.apply_transformation(),
            autoraise=False)
        self.hflip_btn = hflip
        layout.addWidget(hflip)
        vflip = create_toolbutton(
            self,
            text="",
            icon=get_icon("vflip.png"),
            toggled=lambda state: self.apply_transformation(),
            autoraise=False)
        self.vflip_btn = vflip
        layout.addWidget(vflip)
        layout.addSpacing(15)

        self.add_reset_button(layout)

    def reset_transformation(self):
        """Reset transformation"""
        self.angle_combo.setCurrentIndex(1)
        self.hflip_btn.setChecked(False)
        self.vflip_btn.setChecked(False)

    def apply_transformation(self):
        """Apply transformation, e.g. crop or rotate"""
        angle, hflip, vflip = self.get_parameters()
        x, y, _a, px, py, _hf, _vf = self.item.get_transform()
        self.item.set_transform(x, y, angle * np.pi / 180, px, py, hflip,
                                vflip)
        self.get_plot().replot()

    def compute_transformation(self):
        """Compute transformation, return compute output array"""
        angle, hflip, vflip = self.get_parameters()
        data = self.item.data.copy()
        if hflip:
            data = np.fliplr(data)
        if vflip:
            data = np.flipud(data)
        if angle:
            k = int((-angle % 360) / 90)
            data = np.rot90(data, k)
        return data

    #------Public API----------------------------------------------------------
    def get_parameters(self):
        """Return transform parameters"""
        angle = int(str(self.angle_combo.currentText()))
        hflip = self.hflip_btn.isChecked()
        vflip = self.vflip_btn.isChecked()
        return angle, hflip, vflip

    def set_parameters(self, angle, hflip, vflip):
        """Set transform parameters"""
        angle_index = self.ROTATION_ANGLES.index(str(angle))
        self.angle_combo.setCurrentIndex(angle_index)
        self.hflip_btn.setChecked(hflip)
        self.vflip_btn.setChecked(vflip)
Example #2
0
class FlipRotateMixin(base.BaseTransformMixin):
    """Rotate & Crop mixin class, to be mixed with a class providing the 
    get_plot method, like ImageDialog or FlipRotateWidget (see below)"""
    ROTATION_ANGLES = [str((i-1)*90) for i in range(4)]

    #------BaseTransformMixin API----------------------------------------------
    def add_buttons_to_layout(self, layout):
        """Add tool buttons to layout"""
         # Image orientation
        angle_label = QLabel(_("Angle (°):"))
        layout.addWidget(angle_label)
        self.angle_combo = QComboBox(self)
        self.angle_combo.addItems(self.ROTATION_ANGLES)
        self.angle_combo.setCurrentIndex(1)
        self.angle_combo.currentIndexChanged.connect(
                                 lambda index: self.apply_transformation())
        layout.addWidget(self.angle_combo)
        layout.addSpacing(10)
        
        # Image flipping
        flip_label = QLabel(_("Flip:"))
        layout.addWidget(flip_label)
        hflip = create_toolbutton(self, text="", icon=get_icon("hflip.png"),
                          toggled=lambda state: self.apply_transformation(),
                          autoraise=False)
        self.hflip_btn = hflip
        layout.addWidget(hflip)
        vflip = create_toolbutton(self, text="", icon=get_icon("vflip.png"),
                          toggled=lambda state: self.apply_transformation(),
                          autoraise=False)
        self.vflip_btn = vflip
        layout.addWidget(vflip)
        layout.addSpacing(15)
        
        self.add_reset_button(layout)
    
    def reset_transformation(self):
        """Reset transformation"""
        self.angle_combo.setCurrentIndex(1)
        self.hflip_btn.setChecked(False)
        self.vflip_btn.setChecked(False)

    def apply_transformation(self):
        """Apply transformation, e.g. crop or rotate"""
        angle, hflip, vflip = self.get_parameters()
        x, y, _a, px, py, _hf, _vf = self.item.get_transform()
        self.item.set_transform(x, y, angle*np.pi/180, px, py, hflip, vflip)
        self.get_plot().replot()
    
    def compute_transformation(self):
        """Compute transformation, return compute output array"""
        angle, hflip, vflip = self.get_parameters()
        data = self.item.data.copy()
        if hflip:
            data = np.fliplr(data)
        if vflip:
            data = np.flipud(data)
        if angle:
            k = int( (-angle % 360)/90 )
            data = np.rot90(data, k)
        return data
    
    #------Public API----------------------------------------------------------
    def get_parameters(self):
        """Return transform parameters"""
        angle = int(str(self.angle_combo.currentText()))
        hflip = self.hflip_btn.isChecked()
        vflip = self.vflip_btn.isChecked()
        return angle, hflip, vflip

    def set_parameters(self, angle, hflip, vflip):
        """Set transform parameters"""
        angle_index = self.ROTATION_ANGLES.index(str(angle))
        self.angle_combo.setCurrentIndex(angle_index)
        self.hflip_btn.setChecked(hflip)
        self.vflip_btn.setChecked(vflip)
Example #3
0
class OperationsWidget(QWidget):
    operations_changed = QtCore.pyqtSignal()
    operation_changed = QtCore.pyqtSignal(dict, int)
    operation_added = QtCore.pyqtSignal(dict, int)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.widget_layout = QVBoxLayout()

        title_layout = QHBoxLayout()
        title_layout.addStretch()
        style = "<span style=\'color: #444444\'><b>%s</b></span>"
        title = QLabel(style % "Operations")
        title_layout.addWidget(title)
        title_layout.addStretch()
        self.widget_layout.addLayout(title_layout)

        # Create ListWidget and add 10 items to move around.
        self.list_widget = QListWidget()

        # self.list_widget.setDragDropMode(QAbstractItemView.InternalMove)
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setSortingEnabled(False)
        self.list_widget.currentItemChanged.connect(self._populate_settings_update)
        self.widget_layout.addWidget(self.list_widget)

        otitle_layout = QHBoxLayout()
        otitle_layout.addStretch()
        otitle = QLabel(style % "Operation settings")
        otitle_layout.addWidget(otitle)
        otitle_layout.addStretch()
        self.widget_layout.addLayout(otitle_layout)

        self.operations_combo = QComboBox()
        self.operations_combo.currentIndexChanged.connect(self._populate_settings_add)
        self.widget_layout.addWidget(self.operations_combo)

        self.operation_settings = GenericOperationWidget()
        self.widget_layout.addWidget(self.operation_settings)

        self.toolbar = QToolBar()
        self.toolbar.addAction(get_icon('apply.png'), "Apply/Replace",
                               self._change_operation)
        self.toolbar.addAction(get_icon('editors/edit_add.png'), "Add after",
                               self._add_operation)
        self.toolbar.addAction(get_icon('trash.png'), "Remove",
                               self._remove_operation)


        self.widget_layout.addWidget(self.toolbar)
        self.setLayout(self.widget_layout)

    def populate_available_operations(self, dict):
        """
        Populate combobox with available operation names
        """
        self.operations_combo.addItems(dict)

    def set_operations(self, operations_dict):
        """
        Populate operations list with given dict of operations
        """
        self.list_widget.clear()
        for op in operations_dict:
            self.list_widget.addItem(Operation(op))

    def get_operations(self):
        """
        Return list of operations.
        """
        operations = []
        for i in range(self.list_widget.count()):
            op = self.list_widget.item(i)
            operations.append(op._op)

        return operations

    def _remove_operation(self):
        self.list_widget.takeItem(self.list_widget.currentRow())
        self.operations_changed.emit()

    def _add_operation(self):
        """
        Add operation currently in self.operation_settings to the operation
        list.

        Signals:
        ========
        Emits self.opeartion_added and self.operations_changed on success
        """
        op = self.operation_settings.get_operation()
        current_row = self.list_widget.currentRow()
        self.list_widget.insertItem(current_row + 1, Operation(op))
        index = self.list_widget.model().index(current_row + 1, 0)
        self.list_widget.setCurrentIndex(index)
        self.operation_added.emit(op, current_row + 1)
        self.operations_changed.emit()

    def _change_operation(self):
        """
        Replace currently selected operation with operation in
        self.operation_settings (apply changed settings or replace operation).

        Signals:
        ========
        Emits self.operation_changed and self.operations_changed on success
        """
        op = self.operation_settings.get_operation()
        current_row = self.list_widget.currentRow()
        self.list_widget.takeItem(self.list_widget.currentRow())
        self.list_widget.insertItem(current_row, Operation(op))
        index = self.list_widget.model().index(current_row, 0)
        self.list_widget.setCurrentIndex(index)

        self.operation_changed.emit(op, current_row)
        self.operations_changed.emit()


    def _populate_settings_update(self, item):
        """
        Fill self.operation_settings with details of currently selected
        operation.
        """
        try:
            idx = self.operations_combo.findText(item._op["module"])
            if idx >= 0:
                self.operations_combo.setCurrentIndex(idx)
            self.operation_settings.set_operation(item._op)
        except AttributeError:
            pass

    def _populate_settings_add(self, index):
        self.operation_settings.set_operation({"module": self.operations_combo.currentText()})