Beispiel #1
0
 def createColormap(self, obj):
     self.colormap_editor = QColormapEditor(mode="color")
     items = [
         self.colormap_editor.colormap.itemText(i)
         for i in range(self.colormap_editor.colormap.count())
     ]
     self.colormap_editor.colormap.setCurrentIndex(
         items.index(self.colormap_dropdown.currentText()))
     self.colormap_editor.choseColormap.connect(
         partial(self.updateColormap, recreate=False))
     self.colormap_editor.choseColorIndex.connect(
         partial(self.performActionAndClose, obj))
     self.colormap_editor.show()
     if self.start_timer.isActive():
         self.start_timer.stop()
     if self.end_timer.isActive():
         self.end_timer.stop()
Beispiel #2
0
 def createColormap(self, obj):
     self.colormap_editor = QColormapEditor(mode="color")
     items = [self.colormap_editor.colormap.itemText(i) for i in range(self.colormap_editor.colormap.count())]
     self.colormap_editor.colormap.setCurrentIndex(items.index(self.colormap_dropdown.currentText()))
     self.colormap_editor.choseColormap.connect(partial(self.updateColormap, recreate=False))
     self.colormap_editor.choseColorIndex.connect(partial(self.performActionAndClose, obj))
     self.colormap_editor.show()
     if self.start_timer.isActive():
         self.start_timer.stop()
     if self.end_timer.isActive():
         self.end_timer.stop()
Beispiel #3
0
class LegendEditorWidget(BaseOkWindowWidget):
    def __init__(self, parent=None):
        super(LegendEditorWidget, self).__init__()

        # Variables
        self.level_count = None
        self.cur_button = None
        self.cur_index = None
        self.colormap_editor = None

        # Create Labels
        colormap_label = QtGui.QLabel("Colormap:")
        start_color_label = QtGui.QLabel("Start Color:")
        end_color_label = QtGui.QLabel("End Color:")
        extend_left_label = QtGui.QLabel("Extend Left")
        extend_right_label = QtGui.QLabel("Extend Right")
        custom_fill_label = QtGui.QLabel("Custom Fill")
        labels_label = QtGui.QLabel("Labels:")

        # Timers
        self.start_timer = QtCore.QTimer()
        self.start_timer.setSingleShot(True)
        self.start_timer.setInterval(1000)
        self.start_timer.timeout.connect(self.updateStartColor)

        self.end_timer = QtCore.QTimer()
        self.end_timer.setSingleShot(True)
        self.end_timer.setInterval(1000)
        self.end_timer.timeout.connect(self.updateEndColor)

        # Create colormap dropdown
        self.colormap_dropdown = QtGui.QComboBox()
        self.colormap_dropdown.addItems(legend.get_colormaps())
        self.colormap_dropdown.setCurrentIndex(11)
        self.colormap_dropdown.currentIndexChanged[str].connect(
            self.updateColormap)

        # Create start color spinbox
        self.start_color_spin = StartEndSpin(self.start_timer)
        self.start_color_spin.setRange(1, 255)
        self.start_color_spin.validInput.connect(self.start_timer.start)
        self.start_color_spin.invalidInput.connect(
            self.handleStartColorInvalidInput)

        # Create start colormap editor button
        self.start_color_button = QtGui.QPushButton()
        self.start_color_button.clicked.connect(
            partial(self.createColormap, self.start_color_spin))

        # Create end color spinbox
        self.end_color_spin = StartEndSpin(self.end_timer)
        self.end_color_spin.setRange(1, 255)
        self.end_color_spin.validInput.connect(self.end_timer.start)
        self.end_color_spin.invalidInput.connect(
            self.handleEndColorInvalidInput)

        # Create end colormap editor button
        self.end_color_button = QtGui.QPushButton()
        self.end_color_button.clicked.connect(
            partial(self.createColormap, self.end_color_spin))

        # Create extend check boxes
        extend_left_check = QtGui.QCheckBox()
        extend_left_check.stateChanged.connect(self.updateExtendLeft)
        extend_right_check = QtGui.QCheckBox()
        extend_right_check.stateChanged.connect(self.updateExtendRight)

        # Create custom fill icon
        self.custom_fill_icon = QtGui.QToolButton()
        self.custom_fill_icon.setArrowType(QtCore.Qt.RightArrow)
        self.custom_fill_icon.clicked.connect(self.updateArrowType)

        # Create custom fill section
        self.custom_vertical_layout = QtGui.QVBoxLayout()

        fill_style_layout = QtGui.QHBoxLayout()
        self.fill_button_group = QtGui.QButtonGroup()
        for text in ["Solid", "Hatch", "Pattern"]:
            button = QtGui.QRadioButton(text)
            self.fill_button_group.addButton(button)
            fill_style_layout.addWidget(button)

        self.fill_button_group.buttonClicked.connect(self.changeFillStyle)
        fill_style_layout.insertWidget(0, QtGui.QLabel("Fill Style"))

        self.fill_style_widget = QtGui.QWidget()
        self.fill_style_widget.setLayout(fill_style_layout)

        self.custom_vertical_layout.addWidget(self.fill_style_widget)

        # Create labels section
        labels_layout = QtGui.QHBoxLayout()
        labels_layout.addWidget(labels_label)
        self.labels_button_group = QtGui.QButtonGroup()
        for text in ["Auto", "Manual", "None"]:
            button = QtGui.QRadioButton(text)
            if text == "Auto":
                button.setChecked(True)

            self.labels_button_group.addButton(button)
            labels_layout.addWidget(button)

        self.labels_button_group.buttonClicked.connect(self.manageDictEditor)

        # Create layouts
        colormap_layout = QtGui.QHBoxLayout()
        start_color_layout = QtGui.QHBoxLayout()
        end_color_layout = QtGui.QHBoxLayout()
        extend_layout = QtGui.QHBoxLayout()
        custom_fill_layout = QtGui.QHBoxLayout()

        colormap_layout.addWidget(colormap_label)
        colormap_layout.addWidget(self.colormap_dropdown)

        start_color_layout.addWidget(start_color_label)
        start_color_layout.addWidget(self.start_color_spin)
        start_color_layout.addWidget(self.start_color_button)

        end_color_layout.addWidget(end_color_label)
        end_color_layout.addWidget(self.end_color_spin)
        end_color_layout.addWidget(self.end_color_button)

        extend_layout.addWidget(extend_left_check)
        extend_layout.addWidget(extend_left_label)
        extend_layout.addWidget(extend_right_check)
        extend_layout.addWidget(extend_right_label)
        extend_layout.insertStretch(2, 1)

        custom_fill_layout.addWidget(self.custom_fill_icon)
        custom_fill_layout.addWidget(custom_fill_label)

        # Add preview
        self.setPreview(LegendPreviewWidget())
        self.preview.setMaximumHeight(300)
        self.preview.setMinimumHeight(200)

        # Insert layouts
        self.vertical_layout.insertLayout(1, colormap_layout)
        self.vertical_layout.insertLayout(2, start_color_layout)
        self.vertical_layout.insertLayout(3, end_color_layout)
        self.vertical_layout.insertLayout(4, extend_layout)
        self.vertical_layout.insertLayout(5, custom_fill_layout)
        self.vertical_layout.insertLayout(6, labels_layout)

    def setObject(self, legend):
        self.object = legend

        self.start_color_spin.setValue(self.object.color_1)
        self.updateButtonColor(self.start_color_button, self.object.color_1)
        self.start_color_button.setFixedSize(100, 25)

        self.end_color_spin.setValue(self.object.color_2)
        self.updateButtonColor(self.end_color_button, self.object.color_2)
        self.end_color_button.setFixedSize(100, 25)

        self.preview.setLegendObject(legend)
        self.preview.update()

    def updateColormap(self, cur_item, recreate=True):
        if self.object.colormap.name == cur_item:
            return

        self.object.colormap = cur_item
        items = [
            self.colormap_dropdown.itemText(i)
            for i in range(self.colormap_dropdown.count())
        ]
        self.colormap_dropdown.setCurrentIndex(items.index(cur_item))
        self.preview.update()

        self.level_count = len(self.object.levels)

        self.updateStartColor(recreate=False)
        self.updateEndColor(recreate=False)
        if recreate:
            self.updateCustomFillBox()

    def updateStartColor(self, value=-1, recreate=True):
        if value == -1:
            value = self.start_color_spin.value()
        else:
            self.start_color_spin.setValue(value)

        if self.colormap_editor:
            self.colormap_editor.close()

        self.end_color_spin.min = value
        self.object.color_1 = value
        self.updateButtonColor(self.start_color_button, value)
        self.preview.update()

        if self.custom_fill_icon.arrowType(
        ) == QtCore.Qt.DownArrow and recreate:
            self.updateCustomFillBox()

    def updateEndColor(self, value=-1, recreate=True):
        if value == -1:
            value = self.end_color_spin.value()
        else:
            self.end_color_spin.setValue(value)

        if self.colormap_editor:
            self.colormap_editor.close()

        self.start_color_spin.max = value
        self.object.color_2 = value
        self.updateButtonColor(self.end_color_button, value)
        self.preview.update()

        if self.custom_fill_icon.arrowType(
        ) == QtCore.Qt.DownArrow and recreate:
            self.updateCustomFillBox()

    def updateExtendLeft(self, state):
        self.object.ext_left = state == QtCore.Qt.Checked
        self.preview.update()
        self.updateCustomFillBox()

    def updateExtendRight(self, state):
        self.object.ext_right = state == QtCore.Qt.Checked
        self.preview.update()
        self.updateCustomFillBox()

    def updateArrowType(self):
        if self.custom_fill_icon.arrowType() == QtCore.Qt.RightArrow:
            self.custom_fill_icon.setArrowType(QtCore.Qt.DownArrow)
            self.fill_style_widget.setVisible(True)
            self.vertical_layout.insertLayout(6, self.custom_vertical_layout)
            self.custom_vertical_layout.addWidget(self.createCustomFillBox())
            self.initateFillStyle(self.fill_button_group.button(-2))
        else:
            self.object.fill_style = "Solid"
            self.fill_style_widget.setVisible(False)
            self.deleteCustomFillBox()
            self.custom_fill_icon.setArrowType(QtCore.Qt.RightArrow)

        self.preview.update()

    def initateFillStyle(self, old_button):
        """Used when creating custom fill to initalize fill style to Solid"""
        for button in self.fill_button_group.buttons():
            if button.text() == old_button.text():
                button.click()

    def updateCustomFillBox(self):
        if self.custom_fill_icon.arrowType() == QtCore.Qt.DownArrow:
            self.deleteCustomFillBox()
            self.custom_vertical_layout.addWidget(self.createCustomFillBox())
            self.vertical_layout.insertLayout(6, self.custom_vertical_layout)
            self.initateFillStyle(self.fill_button_group.checkedButton())

    def createCustomFillBox(self):
        # create layout for custom fill
        scroll_area = ForceResizeScrollArea()
        grid_layout = DynamicGridLayout(400)
        dynamic_widget = QtGui.QWidget()
        dynamic_widget.setLayout(grid_layout)
        scroll_area.setWidgetResizable(True)
        level_names = self.object.level_names
        grid_widgets = []

        # populate rows
        for index, label in enumerate(level_names):
            color = self.object.level_color(index)
            item = CustomFillWidget(index, label, color)
            item.colorChanged.connect(self.object.set_level_color)
            item.opacityChanged.connect(self.object.set_level_opacity)
            item.buttonColorChanged.connect(self.updateButtonColor)
            item.patternChanged.connect(self.object.set_level_pattern)
            item.colormapChanged.connect(self.updateButtonColor)
            item.createColormapRequest.connect(self.createColormap)
            item.setColor(color)
            item.changeOpacity(100)
            item.attributeChanged.connect(self.preview.update)
            grid_widgets.append(item)

        # adding widgets(plural) only calls build grid once instead of once for each widget
        grid_layout.setColumnWidth(
            int(grid_widgets[-1].minimumSizeHint().width()))
        grid_layout.addNewWidgets(grid_widgets)
        scroll_area.setWidget(dynamic_widget)

        return scroll_area

    def deleteCustomFillBox(self):
        self.vertical_layout.takeAt(6)
        scroll = self.custom_vertical_layout.takeAt(1).widget()
        scroll.deleteLater()

    def changeFillStyle(self, button):
        old_fill_style = self.object.fill_style
        scroll = self.custom_vertical_layout.itemAt(1).widget()
        w = scroll.widget()
        for widget in w.layout().getWidgets():
            row = widget.layout()
            if not row:
                break
            if button.text() == "Solid":
                row.itemAt(2).widget().show()
                row.itemAt(4).widget().hide()

            elif button.text() == "Hatch":
                if old_fill_style == "solid":
                    row.itemAt(4).widget().show()
                else:
                    row.itemAt(2).widget().show()

            elif button.text() == "Pattern":
                row.itemAt(2).widget().hide()
                row.itemAt(4).widget().show()
        self.object.fill_style = button.text()
        self.preview.update()

    def createColormap(self, obj):
        self.colormap_editor = QColormapEditor(mode="color")
        items = [
            self.colormap_editor.colormap.itemText(i)
            for i in range(self.colormap_editor.colormap.count())
        ]
        self.colormap_editor.colormap.setCurrentIndex(
            items.index(self.colormap_dropdown.currentText()))
        self.colormap_editor.choseColormap.connect(
            partial(self.updateColormap, recreate=False))
        self.colormap_editor.choseColorIndex.connect(
            partial(self.performActionAndClose, obj))
        self.colormap_editor.show()
        if self.start_timer.isActive():
            self.start_timer.stop()
        if self.end_timer.isActive():
            self.end_timer.stop()

    def performActionAndClose(self, obj, color_index=0):
        self.colormap_editor.close()
        if isinstance(obj, QtGui.QSpinBox):
            obj.setValue(color_index)
        else:
            obj(color_index)

    def manageDictEditor(self, button):
        self.object.label_mode = button.text()
        if button.text() == "Manual":
            label_editor = DictEditorWidget()
            labels = self.object.labels
            label_editor.setDict(labels)
            label_editor.dictEdited.connect(self.updateLabels)
            scroll_area = QtGui.QScrollArea()
            scroll_area.setWidgetResizable(True)
            scroll_area.setWidget(label_editor)
            self.vertical_layout.insertWidget(self.vertical_layout.count() - 1,
                                              scroll_area)
        elif isinstance(
                self.vertical_layout.itemAt(self.vertical_layout.count() -
                                            2).widget(), QtGui.QScrollArea):
            scroll_area = self.vertical_layout.takeAt(
                self.vertical_layout.count() - 2).widget()
            scroll_area.deleteLater()

    def updateLabels(self, dict):
        try:
            d = {float(key): value for key, value in dict.items()}
            self.object.labels = d
        except ValueError:
            pass

        self.preview.update()

    def updateButtonColor(self, button, color_index):
        r, g, b, a = self.object.rgba_from_index(color_index)
        style_string = "background-color: rgba(%d, %d, %d, %d);" % (r, g, b, a)
        button.setStyleSheet(style_string)

    def handleStartColorInvalidInput(self):
        self.start_timer.stop()
        self.start_color_button.setStyleSheet(
            self.start_color_button.styleSheet() + "border: 1px solid red;")

    def handleEndColorInvalidInput(self):
        self.end_timer.stop()
        self.end_color_button.setStyleSheet(
            self.end_color_button.styleSheet() + "border: 1px solid red;")
Beispiel #4
0
class LegendEditorWidget(BaseOkWindowWidget):
    def __init__(self, parent=None):
        super(LegendEditorWidget, self).__init__()

        # Variables
        self.level_count = None
        self.cur_button = None
        self.cur_index = None
        self.colormap_editor = None

        # Create Labels
        colormap_label = QtGui.QLabel("Colormap:")
        start_color_label = QtGui.QLabel("Start Color:")
        end_color_label = QtGui.QLabel("End Color:")
        extend_left_label = QtGui.QLabel("Extend Left")
        extend_right_label = QtGui.QLabel("Extend Right")
        custom_fill_label = QtGui.QLabel("Custom Fill")
        labels_label = QtGui.QLabel("Labels:")

        # Timers
        self.start_timer = QtCore.QTimer()
        self.start_timer.setSingleShot(True)
        self.start_timer.setInterval(1000)
        self.start_timer.timeout.connect(self.updateStartColor)

        self.end_timer = QtCore.QTimer()
        self.end_timer.setSingleShot(True)
        self.end_timer.setInterval(1000)
        self.end_timer.timeout.connect(self.updateEndColor)

        # Create colormap dropdown
        self.colormap_dropdown = QtGui.QComboBox()
        self.colormap_dropdown.addItems(legend.get_colormaps())
        self.colormap_dropdown.setCurrentIndex(11)
        self.colormap_dropdown.currentIndexChanged[str].connect(self.updateColormap)

        # Create start color spinbox
        self.start_color_spin = StartEndSpin(self.start_timer)
        self.start_color_spin.setRange(1, 255)
        self.start_color_spin.validInput.connect(self.start_timer.start)
        self.start_color_spin.invalidInput.connect(self.handleStartColorInvalidInput)

        # Create start colormap editor button
        self.start_color_button = QtGui.QPushButton()
        self.start_color_button.clicked.connect(partial(self.createColormap, self.start_color_spin))

        # Create end color spinbox
        self.end_color_spin = StartEndSpin(self.end_timer)
        self.end_color_spin.setRange(1, 255)
        self.end_color_spin.validInput.connect(self.end_timer.start)
        self.end_color_spin.invalidInput.connect(self.handleEndColorInvalidInput)

        # Create end colormap editor button
        self.end_color_button = QtGui.QPushButton()
        self.end_color_button.clicked.connect(partial(self.createColormap, self.end_color_spin))

        # Create extend check boxes
        extend_left_check = QtGui.QCheckBox()
        extend_left_check.stateChanged.connect(self.updateExtendLeft)
        extend_right_check = QtGui.QCheckBox()
        extend_right_check.stateChanged.connect(self.updateExtendRight)

        # Create custom fill icon
        self.custom_fill_icon = QtGui.QToolButton()
        self.custom_fill_icon.setArrowType(QtCore.Qt.RightArrow)
        self.custom_fill_icon.clicked.connect(self.updateArrowType)

        # Create custom fill section
        self.custom_vertical_layout = QtGui.QVBoxLayout()

        fill_style_layout = QtGui.QHBoxLayout()
        self.fill_button_group = QtGui.QButtonGroup()
        for text in ["Solid", "Hatch", "Pattern"]:
            button = QtGui.QRadioButton(text)
            self.fill_button_group.addButton(button)
            fill_style_layout.addWidget(button)

        self.fill_button_group.buttonClicked.connect(self.changeFillStyle)
        fill_style_layout.insertWidget(0, QtGui.QLabel("Fill Style"))

        self.fill_style_widget = QtGui.QWidget()
        self.fill_style_widget.setLayout(fill_style_layout)

        self.custom_vertical_layout.addWidget(self.fill_style_widget)

        # Create labels section
        labels_layout = QtGui.QHBoxLayout()
        labels_layout.addWidget(labels_label)
        self.labels_button_group = QtGui.QButtonGroup()
        for text in ["Auto", "Manual", "None"]:
            button = QtGui.QRadioButton(text)
            if text == "Auto":
                button.setChecked(True)

            self.labels_button_group.addButton(button)
            labels_layout.addWidget(button)

        self.labels_button_group.buttonClicked.connect(self.manageDictEditor)

        # Create layouts
        colormap_layout = QtGui.QHBoxLayout()
        start_color_layout = QtGui.QHBoxLayout()
        end_color_layout = QtGui.QHBoxLayout()
        extend_layout = QtGui.QHBoxLayout()
        custom_fill_layout = QtGui.QHBoxLayout()

        colormap_layout.addWidget(colormap_label)
        colormap_layout.addWidget(self.colormap_dropdown)

        start_color_layout.addWidget(start_color_label)
        start_color_layout.addWidget(self.start_color_spin)
        start_color_layout.addWidget(self.start_color_button)

        end_color_layout.addWidget(end_color_label)
        end_color_layout.addWidget(self.end_color_spin)
        end_color_layout.addWidget(self.end_color_button)

        extend_layout.addWidget(extend_left_check)
        extend_layout.addWidget(extend_left_label)
        extend_layout.addWidget(extend_right_check)
        extend_layout.addWidget(extend_right_label)
        extend_layout.insertStretch(2, 1)

        custom_fill_layout.addWidget(self.custom_fill_icon)
        custom_fill_layout.addWidget(custom_fill_label)

        # Add preview
        self.setPreview(LegendPreviewWidget())
        self.preview.setMaximumHeight(300)
        self.preview.setMinimumHeight(200)

        # Insert layouts
        self.vertical_layout.insertLayout(1, colormap_layout)
        self.vertical_layout.insertLayout(2, start_color_layout)
        self.vertical_layout.insertLayout(3, end_color_layout)
        self.vertical_layout.insertLayout(4, extend_layout)
        self.vertical_layout.insertLayout(5, custom_fill_layout)
        self.vertical_layout.insertLayout(6, labels_layout)

    def setObject(self, legend):
        self.object = legend

        self.start_color_spin.setValue(self.object.color_1)
        self.updateButtonColor(self.start_color_button, self.object.color_1)
        self.start_color_button.setFixedSize(100, 25)

        self.end_color_spin.setValue(self.object.color_2)
        self.updateButtonColor(self.end_color_button, self.object.color_2)
        self.end_color_button.setFixedSize(100, 25)

        self.preview.setLegendObject(legend)
        self.preview.update()

    def updateColormap(self, cur_item, recreate=True):
        if self.object.colormap.name == cur_item:
            return

        self.object.colormap = cur_item
        items = [self.colormap_dropdown.itemText(i) for i in range(self.colormap_dropdown.count())]
        self.colormap_dropdown.setCurrentIndex(items.index(cur_item))
        self.preview.update()

        self.level_count = len(self.object.levels)

        self.updateStartColor(recreate=False)
        self.updateEndColor(recreate=False)
        if recreate:
            self.updateCustomFillBox()

    def updateStartColor(self, value=-1, recreate=True):
        if value == -1:
            value = self.start_color_spin.value()
        else:
            self.start_color_spin.setValue(value)

        if self.colormap_editor:
            self.colormap_editor.close()

        self.end_color_spin.min = value
        self.object.color_1 = value
        self.updateButtonColor(self.start_color_button, value)
        self.preview.update()

        if self.custom_fill_icon.arrowType() == QtCore.Qt.DownArrow and recreate:
            self.updateCustomFillBox()

    def updateEndColor(self, value=-1, recreate=True):
        if value == -1:
            value = self.end_color_spin.value()
        else:
            self.end_color_spin.setValue(value)

        if self.colormap_editor:
            self.colormap_editor.close()

        self.start_color_spin.max = value
        self.object.color_2 = value
        self.updateButtonColor(self.end_color_button, value)
        self.preview.update()

        if self.custom_fill_icon.arrowType() == QtCore.Qt.DownArrow and recreate:
            self.updateCustomFillBox()

    def updateExtendLeft(self, state):
        self.object.ext_left = state == QtCore.Qt.Checked
        self.preview.update()
        self.updateCustomFillBox()

    def updateExtendRight(self, state):
        self.object.ext_right = state == QtCore.Qt.Checked
        self.preview.update()
        self.updateCustomFillBox()

    def updateArrowType(self):
        if self.custom_fill_icon.arrowType() == QtCore.Qt.RightArrow:
            self.custom_fill_icon.setArrowType(QtCore.Qt.DownArrow)
            self.fill_style_widget.setVisible(True)
            self.vertical_layout.insertLayout(6, self.custom_vertical_layout)
            self.custom_vertical_layout.addWidget(self.createCustomFillBox())
            self.initateFillStyle(self.fill_button_group.button(-2))
        else:
            self.object.fill_style = "Solid"
            self.fill_style_widget.setVisible(False)
            self.deleteCustomFillBox()
            self.custom_fill_icon.setArrowType(QtCore.Qt.RightArrow)

        self.preview.update()

    def initateFillStyle(self, old_button):
        """Used when creating custom fill to initalize fill style to Solid"""
        for button in self.fill_button_group.buttons():
            if button.text() == old_button.text():
                button.click()

    def updateCustomFillBox(self):
        if self.custom_fill_icon.arrowType() == QtCore.Qt.DownArrow:
            self.deleteCustomFillBox()
            self.custom_vertical_layout.addWidget(self.createCustomFillBox())
            self.vertical_layout.insertLayout(6, self.custom_vertical_layout)
            self.initateFillStyle(self.fill_button_group.checkedButton())

    def createCustomFillBox(self):
        # create layout for custom fill
        scroll_area = ForceResizeScrollArea()
        grid_layout = DynamicGridLayout(400)
        dynamic_widget = QtGui.QWidget()
        dynamic_widget.setLayout(grid_layout)
        scroll_area.setWidgetResizable(True)
        level_names = self.object.level_names
        grid_widgets = []

        # populate rows
        for index, label in enumerate(level_names):
            color = self.object.level_color(index)
            item = CustomFillWidget(index, label, color)
            item.colorChanged.connect(self.object.set_level_color)
            item.opacityChanged.connect(self.object.set_level_opacity)
            item.buttonColorChanged.connect(self.updateButtonColor)
            item.patternChanged.connect(self.object.set_level_pattern)
            item.colormapChanged.connect(self.updateButtonColor)
            item.createColormapRequest.connect(self.createColormap)
            item.setColor(color)
            item.changeOpacity(100)
            item.attributeChanged.connect(self.preview.update)
            grid_widgets.append(item)

        # adding widgets(plural) only calls build grid once instead of once for each widget
        grid_layout.setColumnWidth(int(grid_widgets[-1].minimumSizeHint().width()))
        grid_layout.addNewWidgets(grid_widgets)
        scroll_area.setWidget(dynamic_widget)

        return scroll_area

    def deleteCustomFillBox(self):
        self.vertical_layout.takeAt(6)
        scroll = self.custom_vertical_layout.takeAt(1).widget()
        scroll.deleteLater()

    def changeFillStyle(self, button):
        old_fill_style = self.object.fill_style
        scroll = self.custom_vertical_layout.itemAt(1).widget()
        w = scroll.widget()
        for widget in w.layout().getWidgets():
            row = widget.layout()
            if not row:
                break
            if button.text() == "Solid":
                row.itemAt(2).widget().show()
                row.itemAt(4).widget().hide()

            elif button.text() == "Hatch":
                if old_fill_style == "solid":
                    row.itemAt(4).widget().show()
                else:
                    row.itemAt(2).widget().show()

            elif button.text() == "Pattern":
                row.itemAt(2).widget().hide()
                row.itemAt(4).widget().show()
        self.object.fill_style = button.text()
        self.preview.update()

    def createColormap(self, obj):
        self.colormap_editor = QColormapEditor(mode="color")
        items = [self.colormap_editor.colormap.itemText(i) for i in range(self.colormap_editor.colormap.count())]
        self.colormap_editor.colormap.setCurrentIndex(items.index(self.colormap_dropdown.currentText()))
        self.colormap_editor.choseColormap.connect(partial(self.updateColormap, recreate=False))
        self.colormap_editor.choseColorIndex.connect(partial(self.performActionAndClose, obj))
        self.colormap_editor.show()
        if self.start_timer.isActive():
            self.start_timer.stop()
        if self.end_timer.isActive():
            self.end_timer.stop()

    def performActionAndClose(self, obj, color_index=0):
        self.colormap_editor.close()
        if isinstance(obj, QtGui.QSpinBox):
            obj.setValue(color_index)
        else:
            obj(color_index)

    def manageDictEditor(self, button):
        self.object.label_mode = button.text()
        if button.text() == "Manual":
            label_editor = DictEditorWidget()
            labels = self.object.labels
            label_editor.setDict(labels)
            label_editor.dictEdited.connect(self.updateLabels)
            scroll_area = QtGui.QScrollArea()
            scroll_area.setWidgetResizable(True)
            scroll_area.setWidget(label_editor)
            self.vertical_layout.insertWidget(self.vertical_layout.count() - 1, scroll_area)
        elif isinstance(self.vertical_layout.itemAt(self.vertical_layout.count() - 2).widget(), QtGui.QScrollArea):
            scroll_area = self.vertical_layout.takeAt(self.vertical_layout.count() - 2).widget()
            scroll_area.deleteLater()

    def updateLabels(self, dict):
        try:
            d = {float(key): value for key, value in dict.items()}
            self.object.labels = d
        except ValueError:
            pass

        self.preview.update()

    def updateButtonColor(self, button, color_index):
        r, g, b, a = self.object.rgba_from_index(color_index)
        style_string = "background-color: rgba(%d, %d, %d, %d);" % (r, g, b, a)
        button.setStyleSheet(style_string)

    def handleStartColorInvalidInput(self):
        self.start_timer.stop()
        self.start_color_button.setStyleSheet(
            self.start_color_button.styleSheet() + "border: 1px solid red;")

    def handleEndColorInvalidInput(self):
        self.end_timer.stop()
        self.end_color_button.setStyleSheet(
            self.end_color_button.styleSheet() + "border: 1px solid red;")