def _on_ammo_type_combo_changed(self, beam: str, combo: QComboBox,
                                    is_ammo_b: bool, _):
        with self._editor as editor:
            beam_configuration = editor.configuration.beam_configuration
            old_config: BeamAmmoConfiguration = getattr(
                beam_configuration, beam)
            if is_ammo_b:
                new_config = dataclasses.replace(old_config,
                                                 ammo_b=combo.currentData())
            else:
                new_config = dataclasses.replace(old_config,
                                                 ammo_a=combo.currentData())

            editor.set_configuration_field(
                "beam_configuration",
                dataclasses.replace(beam_configuration, **{beam: new_config}))
Beispiel #2
0
 def _on_default_item_updated(self, category: ItemCategory, combo: QtWidgets.QComboBox, _):
     item: MajorItem = combo.currentData()
     with self._editor as editor:
         new_config = editor.major_items_configuration
         new_config = new_config.replace_default_item(category, item)
         new_config = new_config.replace_state_for_item(
             item,
             MajorItemState(
                 num_included_in_starting_items=1,
                 included_ammo=new_config.items_state[item].included_ammo
             ),
         )
         editor.major_items_configuration = new_config
Beispiel #3
0
class MineSweeper(QMainWindow):
	def __init__(self):
		super().__init__()

		self.undiscovered_color: str = "#000000"
		self.discovered_color: str = "#d9d9d9"
		self.win_timer_color: str = "#e30e0e"
		self.lose_timer_color: str = "#0cc431"


		self.curr_time = QTime(00,00,00)
		self.timer = QTimer()
		self.timer.timeout.connect(self.time)
		self.timer_already_started = False

		self.solved: bool = False
		
		self.player_ended: bool = False

		self.theme: str = "dark"

		self.list_of_mines: list = []

		self.difficulty_slider_default_value: int = 2
		self.number_of_mines: int = mines_number(NUMBER_OF_LABELS, self.difficulty_slider_default_value)


		self.create_GUI()

	def create_GUI(self) -> None:
		self.setWindowTitle("MineSweeper 1.1")

		self.win_massage = QMessageBox(self)
		self.win_massage.setText("Gratuluji, dokázal jsi nalézt všechny miny")

		self.setMouseTracking(True)

		centralWidget = QWidget(self)
		centralWidget.setStyleSheet("background: white")
		self.setCentralWidget(centralWidget)
		self.setFixedSize(X_WINDOW_SIZE + 20, Y_WINDOW_SIZE)

		layout = QGridLayout(centralWidget)
		layout.setSpacing(0)
		layout.setContentsMargins(0, 0, 0, 0)
		centralWidget.setLayout(layout)

		self.list_of_labels: list = []

		self.list_of_mines = generate_mines(self.number_of_mines, X_SIZE, Y_SIZE)

		# RESET BUTTON
		self.reset_button = QPushButton(centralWidget)
		self.reset_button.setText("RESET")
		self.reset_button.clicked.connect(self.reset)
		self.reset_button.setStyleSheet("margin: 3px")
		self.reset_button.setMinimumSize(0, 50)

		# TIMER LABEL
		self.timer_label = QLabel(centralWidget)
		self.timer_label.setText(f"{self.curr_time.minute():0>2}:{self.curr_time.second():0>2}")
		self.timer_label.setAlignment(Qt.AlignHCenter)
		self.timer_label.setStyleSheet("font: 34px")

		# DIFFICULTY SLIDER
		self.difficulty_slider = QSlider(centralWidget)
		self.difficulty_slider.setOrientation(Qt.Horizontal)
		self.difficulty_slider.setFixedHeight(30)
		self.difficulty_slider.setRange(1, 10)
		self.difficulty_slider.setTickInterval(1)
		self.difficulty_slider.setValue(self.difficulty_slider_default_value)
		self.difficulty_slider.valueChanged.connect(self.difficulty_label_set)
		self.difficulty_slider.sliderReleased.connect(self.new_mines_set)

		# DIFFICULTY LABEL
		self.difficulty_label = QLabel(centralWidget)
		self.difficulty_label.setText(str(self.difficulty_slider_default_value))
		self.difficulty_label.setAlignment(Qt.AlignCenter)
		self.difficulty_label.setStyleSheet("font: 20px")
		
		

		for i in range(Y_SIZE):
			row = []
			for j in range(X_SIZE):
				if (i, j) in self.list_of_mines:
					mine = True
				else:
					mine = False

				label = Chunk(j, i, mine)
				label.setFixedSize(FIELD_SQUARE_SIZE, FIELD_SQUARE_SIZE)
				label.setStyleSheet(f"background: {self.undiscovered_color}; border: 1px solid grey")
				layout.addWidget(label, i, j)
				row.append(label)
			self.list_of_labels.append(row)


		self.color_theme_combobox = QComboBox(centralWidget)
		self.color_theme_combobox.addItem("Dark theme", "dark")
		self.color_theme_combobox.addItem("Light theme", "light")
		self.color_theme_combobox.addItem("Color theme", "colorful")
		self.color_theme_combobox.currentIndexChanged.connect(self.theme_change)
		self.color_theme_combobox.setMinimumHeight(FIELD_SQUARE_SIZE * 2)
		if self.theme == "dark":
			self.color_theme_combobox.setCurrentIndex(0)
		elif self.theme == "light":
			self.color_theme_combobox.setCurrentIndex(1)
		else:
			self.color_theme_combobox.setCurrentIndex(2)
		layout.addWidget(self.color_theme_combobox, Y_SIZE - 2, X_SIZE, 2, 1)

		layout.addWidget(self.timer_label, 0, X_SIZE, 3, 1)
		layout.addWidget(self.reset_button, 2, X_SIZE, 3, 1)
		layout.addWidget(self.difficulty_slider, Y_SIZE, 1, 1, X_SIZE - 2)
		layout.addWidget(self.difficulty_label, Y_SIZE, X_SIZE, 1, 1)

		self.mines_number_surroundings_calculate()

	def theme_change(self) -> None:
		if self.color_theme_combobox.currentData() == "light":
			self.undiscovered_color = LIGHT_THEME["undiscovered_color"]
			self.discovered_color = LIGHT_THEME["discovered_color"]
			self.win_timer_color = LIGHT_THEME["win_timer_color"]
			self.lose_timer_color = LIGHT_THEME["lose_timer_color"]
			self.theme = "light"
	
		if self.color_theme_combobox.currentData() == "dark":	
			self.undiscovered_color = DARK_THEME["undiscovered_color"]
			self.discovered_color = DARK_THEME["discovered_color"]
			self.win_timer_color = DARK_THEME["win_timer_color"]
			self.lose_timer_color = DARK_THEME["lose_timer_color"]
			self.theme = "dark"

		if self.color_theme_combobox.currentData() == "colorful":	
			self.undiscovered_color = COLOR_THEME["undiscovered_color"]
			self.discovered_color = COLOR_THEME["discovered_color"]
			self.win_timer_color = COLOR_THEME["win_timer_color"]
			self.lose_timer_color = COLOR_THEME["lose_timer_color"]
			self.theme = "colorful"

		for y in range(Y_SIZE):
			for x in range(X_SIZE):	 
				if self.list_of_labels[y][x].marked:
					pass

				elif not self.list_of_labels[y][x].discovered:
					self.list_of_labels[y][x].setStyleSheet(f"background: {self.undiscovered_color}; border: 1px solid grey")

				elif self.list_of_labels[y][x].discovered:
					self.list_of_labels[y][x].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
		
	def difficulty_label_set(self):
		self.difficulty_label.setText(str(self.difficulty_slider.value()))

	def mousePressEvent(self, QMouseEvent) -> None:
		if not self.player_ended:

			y = QMouseEvent.pos().x()
			x = QMouseEvent.pos().y()

			if not (x > X_GRID_SIZE or y > Y_GRID_SIZE):

				x = closest_smaller_number(x, Y_POSSIBLE_VALUES)
				y = closest_smaller_number(y, X_POSSIBLE_VALUES)

				x = int(x // FIELD_SQUARE_SIZE)
				y = int(y // FIELD_SQUARE_SIZE)

				if QMouseEvent.button() == Qt.LeftButton:
					if self.list_of_labels[x][y].mine:				
						self.stop_timer()
						if not self.player_ended:
							self.list_of_labels[x][y].discovered = True
							self.list_of_labels[x][y].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
							self.list_of_labels[x][y].setPixmap(QPixmap("C:/Data/python/miny/pracovní verze/pictures/bomb_small.png"))
							self.win_massage.about(self, "PROHRA", "Tentokrát se to bohužel nepovedlo, snad to vyjde příště.")
					
						self.player_ended = True
					else:
						if not self.timer_already_started:
							self.start_timer()

						self.timer_already_started = True
						self.list_of_labels[x][y].discovered = True
						self.list_of_labels[x][y].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")

						self.reveal_area(y, x)

					self.solved_check()

				else:
					if not self.list_of_labels[x][y].discovered:
						if self.list_of_labels[x][y].marked:
							self.list_of_labels[x][y].setStyleSheet(f"background: {self.undiscovered_color}; border: 1px solid grey")
							self.list_of_labels[x][y].marked = False

						else:
							self.list_of_labels[x][y].setStyleSheet("background: orange; border: 1px solid grey")
							self.list_of_labels[x][y].marked = True

	def mines_number_surroundings_calculate(self) -> None:
		for x in range(X_SIZE):
			for y in range(Y_SIZE):
				self.list_of_labels[x][y].mines_number_surroundings = 0
				for i in range(x - 1, x + 2):
					for j in range(y - 1, y + 2):
						try:
							if self.list_of_labels[i][j].mine and i >= 0 and j >= 0:
								if not (i == x and j == y):
									self.list_of_labels[x][y].mines_number_surroundings += 1
						except IndexError:
							pass

	def new_mines_set(self):
		self.number_of_mines = mines_number(NUMBER_OF_LABELS, self.difficulty_slider.value())
		self.list_of_mines = generate_mines(self.number_of_mines, X_SIZE, Y_SIZE)
		for y in range(Y_SIZE):
			for x in range(X_SIZE):
				if (y, x) in self.list_of_mines:
					self.list_of_labels[y][x].mine = True
				else:
					self.list_of_labels[y][x].mine = False

		self.mines_number_surroundings_calculate()
		self.label_set()

	def label_set(self) -> None:
		for y in range(Y_SIZE):
			for x in range(X_SIZE):
				if self.list_of_labels[y][x].discovered:
					if self.list_of_labels[y][x].mines_number_surroundings == 0:
						pass
					else:
						self.list_of_labels[y][x].setText(str(self.list_of_labels[y][x].mines_number_surroundings))

	def reveal_area(self, x: int, y: int) -> None:
		if self.list_of_labels[y][x].mines_number_surroundings == 0:		
			try:
				extract = self.list_of_labels[y - 1][x]

				if not extract.mine and Y_SIZE > y - 1 >= 0 and not extract.discovered:
					self.list_of_labels[y - 1][x].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
					self.list_of_labels[y - 1][x].discovered = True
					if extract.mines_number_surroundings == 0:
						self.reveal_area(x, y - 1)

			except IndexError:
				pass

			try:
				extract = self.list_of_labels[y + 1][x]

				if not extract.mine and Y_SIZE > y + 1 >= 0 and not extract.discovered:
					self.list_of_labels[y + 1][x].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
					self.list_of_labels[y + 1][x].discovered = True
					if extract.mines_number_surroundings == 0:
						self.reveal_area(x, y + 1)

			except IndexError:
				pass

			try:
				extract = self.list_of_labels[y][x + 1]

				if not extract.mine and X_SIZE > x + 1 >= 0 and not extract.discovered:
					self.list_of_labels[y][x + 1].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
					self.list_of_labels[y][x + 1].discovered = True
					if extract.mines_number_surroundings == 0:
						self.reveal_area(x + 1, y)

			except IndexError:
				pass

			try:
				extract = self.list_of_labels[y][x - 1]

				if not extract.mine and X_SIZE - 1 > x  - 1 >= 0 and not extract.discovered:
					self.list_of_labels[y][x - 1].setStyleSheet(f"background: {self.discovered_color}; border: 1px solid grey")
					self.list_of_labels[y][x - 1].discovered = True
					if extract.mines_number_surroundings == 0:
						self.reveal_area(x - 1, y)

			except IndexError:
				pass

		self.label_set()

	def solved_check(self) -> None:
		for element in self.list_of_labels:
			for part in element:
				if not part.mine and not part.discovered:
					return

		self.solved = True
		self.stop_timer()

		if not self.player_ended:
			self.player_ended = True
			self.win_massage.about(self, "VÝHRA", f"Gratuluji, zvládl/a jsi vyřešit tento problém. Zvládl/a jsi to za {self.curr_time.minute():0>2}:{self.curr_time.second():0>2}")

	# TIMER FUNCIONS
	def start_timer(self) -> None:
		self.difficulty_slider.setDisabled(True)
		self.timer.start(1000)
		
	def stop_timer(self) -> None:
		self.timer.stop()
		if not self.solved:
			self.timer_label.setStyleSheet(f"font: 34px; color: {self.win_timer_color}")
		else:
			self.timer_label.setStyleSheet(f"font: 34px; color: {self.lose_timer_color}")

	def time(self) -> None:
		self.curr_time = self.curr_time.addSecs(1)
		self.timer_label.setText(f"{self.curr_time.minute():0>2}:{self.curr_time.second():0>2}")

	#RESET
	def reset(self) -> None:
		self.timer = QTimer()
		self.curr_time = QTime(00,00,00)
		self.timer.timeout.connect(self.time)
		self.solved = False
		self.timer_already_started = False
		self.player_ended = False
		self.difficulty_slider.setDisabled(False)
		self.difficulty_slider_default_value = self.difficulty_slider.value()
		self.create_GUI()
 def _on_gate_combo_box_changed(self, combo: QComboBox, new_index: int):
     with self._editor as editor:
         editor.set_configuration_field(
             "translator_configuration",
             _translator_config(editor).replace_requirement_for_gate(
                 combo.identifier, combo.currentData()))
Beispiel #5
0
class RequirementEditor:
    _editor: Union[None, ResourceRequirementEditor, ArrayRequirementEditor,
                   TemplateRequirementEditor]

    def __init__(self,
                 parent: QWidget,
                 parent_layout: QVBoxLayout,
                 resource_database: ResourceDatabase,
                 *,
                 on_remove=None):

        self.parent = parent
        self.parent_layout = parent_layout
        self.resource_database = resource_database
        self._editor = None
        self._last_resource = None
        self._last_items = ()
        self._last_comment = None

        self.line_layout = QHBoxLayout()
        self.line_layout.setAlignment(Qt.AlignLeft)
        self.parent_layout.addLayout(self.line_layout)

        if on_remove is not None:
            self.remove_button = QtWidgets.QToolButton(parent)
            self.remove_button.setText("X")
            self.remove_button.setMaximumWidth(20)
            self.remove_button.clicked.connect(on_remove)
            self.line_layout.addWidget(self.remove_button)
        else:
            self.remove_button = None

        self.requirement_type_combo = QComboBox(parent)
        self.requirement_type_combo.addItem("Resource", ResourceRequirement)
        self.requirement_type_combo.addItem("Or", RequirementOr)
        self.requirement_type_combo.addItem("And", RequirementAnd)
        if resource_database.requirement_template:
            self.requirement_type_combo.addItem("Template",
                                                RequirementTemplate)
        self.requirement_type_combo.setMaximumWidth(75)
        self.requirement_type_combo.activated.connect(
            self._on_change_requirement_type)
        self.line_layout.addWidget(self.requirement_type_combo)

    def create_specialized_editor(self, requirement: Requirement):
        self.requirement_type_combo.setCurrentIndex(
            self.requirement_type_combo.findData(type(requirement)))

        if isinstance(requirement, ResourceRequirement):
            self._editor = ResourceRequirementEditor(self.parent,
                                                     self.line_layout,
                                                     self.resource_database,
                                                     requirement)

        elif isinstance(requirement, RequirementArrayBase):
            self._editor = ArrayRequirementEditor(self.parent,
                                                  self.parent_layout,
                                                  self.line_layout,
                                                  self.resource_database,
                                                  requirement)

        elif isinstance(requirement, RequirementTemplate):
            self._editor = TemplateRequirementEditor(self.parent,
                                                     self.line_layout,
                                                     self.resource_database,
                                                     requirement)

        else:
            raise RuntimeError(
                f"Unknown requirement type: {type(requirement)} - {requirement}"
            )

    def _on_change_requirement_type(self):
        current_requirement = self.current_requirement
        self._editor.deleteLater()

        if isinstance(current_requirement, ResourceRequirement):
            self._last_resource = current_requirement

        elif isinstance(current_requirement, RequirementArrayBase):
            self._last_items = current_requirement.items
            self._last_comment = current_requirement.comment

        elif isinstance(current_requirement, RequirementTemplate):
            pass

        else:
            raise RuntimeError(
                f"Unknown requirement type: {type(current_requirement)} - {current_requirement}"
            )

        new_class = self.requirement_type_combo.currentData()
        if new_class == ResourceRequirement:
            if self._last_resource is None:
                new_requirement = _create_default_resource_requirement(
                    self.resource_database)
            else:
                new_requirement = self._last_resource
        elif new_class == RequirementTemplate:
            new_requirement = _create_default_template_requirement(
                self.resource_database)
        else:
            new_requirement = new_class(self._last_items, self._last_comment)

        self.create_specialized_editor(new_requirement)

    def deleteLater(self):
        if self.remove_button is not None:
            self.remove_button.deleteLater()

        self.requirement_type_combo.deleteLater()

        if self._editor is not None:
            self._editor.deleteLater()

    @property
    def current_requirement(self) -> Requirement:
        return self._editor.current_requirement
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setDynamicSortFilter(True)

        self.sourceGroupBox = QGroupBox("Original Model")
        self.proxyGroupBox = QGroupBox("Sorted/Filtered Model")

        self.sourceView = QTreeView()
        self.sourceView.setRootIsDecorated(False)
        self.sourceView.setAlternatingRowColors(True)

        self.proxyView = QTreeView()
        self.proxyView.setRootIsDecorated(False)
        self.proxyView.setAlternatingRowColors(True)
        self.proxyView.setModel(self.proxyModel)
        self.proxyView.setSortingEnabled(True)

        self.sortCaseSensitivityCheckBox = QCheckBox("Case sensitive sorting")
        self.filterCaseSensitivityCheckBox = QCheckBox("Case sensitive filter")

        self.filterPatternLineEdit = QLineEdit()
        self.filterPatternLineEdit.setClearButtonEnabled(True)
        self.filterPatternLabel = QLabel("&Filter pattern:")
        self.filterPatternLabel.setBuddy(self.filterPatternLineEdit)

        self.filterSyntaxComboBox = QComboBox()
        self.filterSyntaxComboBox.addItem("Regular expression",
                                          REGULAR_EXPRESSION)
        self.filterSyntaxComboBox.addItem("Wildcard",
                                          WILDCARD)
        self.filterSyntaxComboBox.addItem("Fixed string",
                                          FIXED_STRING)
        self.filterSyntaxLabel = QLabel("Filter &syntax:")
        self.filterSyntaxLabel.setBuddy(self.filterSyntaxComboBox)

        self.filterColumnComboBox = QComboBox()
        self.filterColumnComboBox.addItem("Subject")
        self.filterColumnComboBox.addItem("Sender")
        self.filterColumnComboBox.addItem("Date")
        self.filterColumnLabel = QLabel("Filter &column:")
        self.filterColumnLabel.setBuddy(self.filterColumnComboBox)

        self.filterPatternLineEdit.textChanged.connect(self.filterRegExpChanged)
        self.filterSyntaxComboBox.currentIndexChanged.connect(self.filterRegExpChanged)
        self.filterColumnComboBox.currentIndexChanged.connect(self.filterColumnChanged)
        self.filterCaseSensitivityCheckBox.toggled.connect(self.filterRegExpChanged)
        self.sortCaseSensitivityCheckBox.toggled.connect(self.sortChanged)

        sourceLayout = QHBoxLayout()
        sourceLayout.addWidget(self.sourceView)
        self.sourceGroupBox.setLayout(sourceLayout)

        proxyLayout = QGridLayout()
        proxyLayout.addWidget(self.proxyView, 0, 0, 1, 3)
        proxyLayout.addWidget(self.filterPatternLabel, 1, 0)
        proxyLayout.addWidget(self.filterPatternLineEdit, 1, 1, 1, 2)
        proxyLayout.addWidget(self.filterSyntaxLabel, 2, 0)
        proxyLayout.addWidget(self.filterSyntaxComboBox, 2, 1, 1, 2)
        proxyLayout.addWidget(self.filterColumnLabel, 3, 0)
        proxyLayout.addWidget(self.filterColumnComboBox, 3, 1, 1, 2)
        proxyLayout.addWidget(self.filterCaseSensitivityCheckBox, 4, 0, 1, 2)
        proxyLayout.addWidget(self.sortCaseSensitivityCheckBox, 4, 2)
        self.proxyGroupBox.setLayout(proxyLayout)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.sourceGroupBox)
        mainLayout.addWidget(self.proxyGroupBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Basic Sort/Filter Model")
        self.resize(500, 450)

        self.proxyView.sortByColumn(1, Qt.AscendingOrder)
        self.filterColumnComboBox.setCurrentIndex(1)

        self.filterPatternLineEdit.setText("Andy|Grace")
        self.filterCaseSensitivityCheckBox.setChecked(True)
        self.sortCaseSensitivityCheckBox.setChecked(True)

    def setSourceModel(self, model):
        self.proxyModel.setSourceModel(model)
        self.sourceView.setModel(model)

    def filterRegExpChanged(self):
        syntax_nr = self.filterSyntaxComboBox.currentData()
        pattern = self.filterPatternLineEdit.text()
        if syntax_nr == WILDCARD:
            pattern = QRegularExpression.wildcardToRegularExpression(pattern)
        elif syntax_nr == FIXED_STRING:
            pattern = QRegularExpression.escape(pattern)

        regExp = QRegularExpression(pattern)
        if not self.filterCaseSensitivityCheckBox.isChecked():
            options = regExp.patternOptions()
            options |= QRegularExpression.CaseInsensitiveOption
            regExp.setPatternOptions(options)
        self.proxyModel.setFilterRegularExpression(regExp)

    def filterColumnChanged(self):
        self.proxyModel.setFilterKeyColumn(self.filterColumnComboBox.currentIndex())

    def sortChanged(self):
        if self.sortCaseSensitivityCheckBox.isChecked():
            caseSensitivity = Qt.CaseSensitive
        else:
            caseSensitivity = Qt.CaseInsensitive

        self.proxyModel.setSortCaseSensitivity(caseSensitivity)
Beispiel #7
0
class ItemRow:
    def __init__(self, parent: QWidget, parent_layout: QVBoxLayout,
                 resource_database: ResourceDatabase,
                 item: ResourceRequirement, rows: List["ItemRow"]):
        self.parent = parent
        self.resource_database = resource_database
        self._rows = rows
        rows.append(self)

        self.layout = QHBoxLayout()
        self.layout.setObjectName(f"Box layout for {item.resource.long_name}")
        parent_layout.addLayout(self.layout)

        self.resource_type_combo = _create_resource_type_combo(
            item.resource.resource_type, parent)
        self.resource_type_combo.setMinimumWidth(75)
        self.resource_type_combo.setMaximumWidth(75)

        self.resource_name_combo = _create_resource_name_combo(
            self.resource_database, item.resource.resource_type, item.resource,
            self.parent)

        self.negate_combo = QComboBox(parent)
        self.negate_combo.addItem("≥", False)
        self.negate_combo.addItem("<", True)
        self.negate_combo.setCurrentIndex(int(item.negate))
        self.negate_combo.setMinimumWidth(40)
        self.negate_combo.setMaximumWidth(40)

        self.amount_edit = QLineEdit(parent)
        self.amount_edit.setValidator(QIntValidator(1, 10000))
        self.amount_edit.setText(str(item.amount))
        self.amount_edit.setMinimumWidth(45)
        self.amount_edit.setMaximumWidth(45)

        self.remove_button = QPushButton(parent)
        self.remove_button.setText("X")
        self.remove_button.setMaximumWidth(20)

        self.layout.addWidget(self.resource_type_combo)
        self.layout.addWidget(self.resource_name_combo)
        self.layout.addWidget(self.negate_combo)
        self.layout.addWidget(self.amount_edit)
        self.layout.addWidget(self.remove_button)

        self.resource_type_combo.currentIndexChanged.connect(self._update_type)
        self.remove_button.clicked.connect(self._delete_row)

    def _update_type(self):
        old_combo = self.resource_name_combo
        self.resource_name_combo = _create_resource_name_combo(
            self.resource_database, self.resource_type_combo.currentData(),
            None, self.parent)

        self.layout.replaceWidget(old_combo, self.resource_name_combo)
        old_combo.deleteLater()

    def _delete_row(self):
        self.resource_type_combo.deleteLater()
        self.resource_name_combo.deleteLater()
        self.negate_combo.deleteLater()
        self.amount_edit.deleteLater()
        self.remove_button.deleteLater()
        self.layout.deleteLater()
        self._rows.remove(self)

    @property
    def current_individual(self) -> ResourceRequirement:
        return ResourceRequirement(self.resource_name_combo.currentData(),
                                   int(self.amount_edit.text()),
                                   self.negate_combo.currentData())
Beispiel #8
0
class ParameterEditorItem(QWidget):
    onRemoveParameter = Signal(Parameter)
    onMoveParameterUp = Signal(Parameter)
    onMoveParameterDown = Signal(Parameter)
    onChanged = Signal()

    def __init__(self, parameter: Parameter):
        super().__init__()

        self.parameter = parameter

        deleteButton = QToolButton()
        deleteButton.setText("X")
        deleteButton.clicked.connect(
            lambda: self.onRemoveParameter.emit(self.parameter))
        upButton = QToolButton()
        upButton.setText("\u2191")
        upButton.clicked.connect(
            lambda: self.onMoveParameterUp.emit(self.parameter))
        downButton = QToolButton()
        downButton.setText("\u2193")
        downButton.clicked.connect(
            lambda: self.onMoveParameterDown.emit(self.parameter))

        buttonsLayout = QVBoxLayout()
        buttonsLayout.setAlignment(Qt.AlignTop)
        buttonsLayout.addWidget(deleteButton)
        buttonsLayout.addWidget(upButton)
        buttonsLayout.addWidget(downButton)

        self._nameLabel = QLabel("Name")
        self._nameField = QLineEdit()
        self._nameField.textChanged.connect(self.OnChanged)

        self._dataTypeLabel = QLabel("Data Type")
        self._dataTypeField = QComboBox()
        for dataType in DataType:
            self._dataTypeField.addItem(dataType.ToString(), userData=dataType)
        self._dataTypeField.currentIndexChanged.connect(self.OnChanged)

        self._defaultValueLabel = QLabel("Default Value")
        self._defaultInteger = QSpinBox()
        self._defaultInteger.valueChanged.connect(self.OnChanged)

        self._defaultFloat = QDoubleSpinBox()
        self._defaultFloat.valueChanged.connect(self.OnChanged)

        self._defaultBoolean = QComboBox()
        self._defaultBoolean.addItem("True", True)
        self._defaultBoolean.addItem("False", False)
        self._defaultBoolean.currentIndexChanged.connect(self.OnChanged)

        self._defaultString = QLineEdit()
        self._defaultString.textChanged.connect(self.OnChanged)

        self._minimumLabel = QLabel("Minimum")
        self._minimumFloat = QDoubleSpinBox()
        self._minimumFloat.valueChanged.connect(self.OnChanged)
        self._minimumInteger = QSpinBox()
        self._minimumInteger.valueChanged.connect(self.OnChanged)

        self._maximumLabel = QLabel("Maximum")
        self._maximumFloat = QDoubleSpinBox()
        self._maximumFloat.valueChanged.connect(self.OnChanged)
        self._maximumInteger = QSpinBox()
        self._maximumInteger.valueChanged.connect(self.OnChanged)

        gridLayout = QGridLayout()
        gridLayout.setAlignment(Qt.AlignTop)
        gridLayout.addWidget(self._nameLabel, 0, 0)
        gridLayout.addWidget(self._nameField, 0, 1)
        gridLayout.addWidget(self._dataTypeLabel, 1, 0)
        gridLayout.addWidget(self._dataTypeField, 1, 1)
        gridLayout.addWidget(self._defaultValueLabel, 2, 0)

        for defaultField in [
                self._defaultInteger, self._defaultFloat, self._defaultBoolean,
                self._defaultString
        ]:
            gridLayout.addWidget(defaultField, 2, 1)

        gridLayout.addWidget(self._minimumLabel, 3, 0)
        gridLayout.addWidget(self._minimumInteger, 3, 1)
        gridLayout.addWidget(self._minimumFloat, 3, 1)
        gridLayout.addWidget(self._maximumLabel, 4, 0)
        gridLayout.addWidget(self._maximumInteger, 4, 1)
        gridLayout.addWidget(self._maximumFloat, 4, 1)

        layout = QHBoxLayout()
        layout.addLayout(buttonsLayout)
        layout.addLayout(gridLayout)
        self.setLayout(layout)

        self.SetFieldsFromParameter()

    def SetFieldsFromParameter(self):
        self._nameField.setText(self.parameter.name)

        self._dataTypeField.setCurrentText(self.parameter.dataType.ToString())

        minFloat, maxFloat = self.parameter.minimumFloat, self.parameter.maximumFloat
        minInt, maxInt = self.parameter.minimumInteger, self.parameter.maximumInteger
        self._minimumFloat.setRange(-2**30, maxFloat)
        self._maximumFloat.setRange(minFloat, 2**30)
        self._minimumInteger.setRange(-2**30, maxInt)
        self._maximumInteger.setRange(minInt, 2**30)
        if self._minimumFloat.value() != minFloat:
            self._minimumFloat.setValue(minFloat)
        if self._maximumFloat.value() != maxFloat:
            self._maximumFloat.setValue(maxFloat)
        if self._minimumInteger.value() != minInt:
            self._minimumInteger.setValue(minInt)
        if self._maximumInteger.value() != maxInt:
            self._maximumInteger.setValue(maxInt)

        self._defaultInteger.setRange(minInt, maxInt)
        self._defaultFloat.setRange(minFloat, maxFloat)
        if self._defaultInteger.value() != self.parameter.defaultValueDict[
                DataType.INTEGER]:
            self._defaultInteger.setValue(
                self.parameter.defaultValueDict[DataType.INTEGER])
        if self._defaultFloat.value() != self.parameter.defaultValueDict[
                DataType.FLOAT]:
            self._defaultFloat.setValue(
                self.parameter.defaultValueDict[DataType.FLOAT])

        if self._defaultBoolean.currentData(
        ) != self.parameter.defaultValueDict[DataType.BOOLEAN]:
            self._defaultBoolean.setCurrentText(
                str(self.parameter.defaultValueDict[DataType.BOOLEAN]))

        if self._defaultString.text() != self.parameter.defaultValueDict[
                DataType.STRING]:
            self._defaultString.setText(
                self.parameter.defaultValueDict[DataType.STRING])

        self.UpdateVisibility()

    def UpdateVisibility(self):
        self._defaultInteger.setVisible(
            self._dataTypeField.currentData() is DataType.INTEGER)
        self._defaultFloat.setVisible(
            self._dataTypeField.currentData() is DataType.FLOAT)
        self._defaultBoolean.setVisible(
            self._dataTypeField.currentData() is DataType.BOOLEAN)
        self._defaultString.setVisible(
            self._dataTypeField.currentData() is DataType.STRING)

        self._minimumLabel.setVisible(self._dataTypeField.currentData() in
                                      [DataType.INTEGER, DataType.FLOAT])
        self._maximumLabel.setVisible(self._dataTypeField.currentData() in
                                      [DataType.INTEGER, DataType.FLOAT])
        self._minimumInteger.setVisible(
            self._dataTypeField.currentData() is DataType.INTEGER)
        self._maximumInteger.setVisible(
            self._dataTypeField.currentData() is DataType.INTEGER)
        self._minimumFloat.setVisible(
            self._dataTypeField.currentData() is DataType.FLOAT)
        self._maximumFloat.setVisible(
            self._dataTypeField.currentData() is DataType.FLOAT)
        self._minimumLabel.setVisible(self._dataTypeField.currentData() in
                                      [DataType.INTEGER, DataType.FLOAT])
        self._maximumLabel.setVisible(self._dataTypeField.currentData() in
                                      [DataType.INTEGER, DataType.FLOAT])

        self._defaultValueLabel.setVisible(self._dataTypeField.currentData(
        ) not in [DataType.VALVE, DataType.PROGRAM, DataType.PROGRAM_PRESET])

    def OnChanged(self):
        self.UpdateVisibility()
        self._minimumFloat.setMaximum(self._maximumFloat.value())
        self._maximumFloat.setMinimum(self._minimumFloat.value())
        self._minimumInteger.setMaximum(self._maximumInteger.value())
        self._maximumInteger.setMinimum(self._minimumInteger.value())
        self._defaultInteger.setRange(self._minimumInteger.value(),
                                      self._maximumInteger.value())
        self._defaultFloat.setRange(self._minimumFloat.value(),
                                    self._maximumFloat.value())
        self.onChanged.emit()

    def UpdateParameter(self):
        self.parameter.name = self._nameField.text()
        self.parameter.dataType = self._dataTypeField.currentData()

        self.parameter.defaultValueDict[
            DataType.INTEGER] = self._defaultInteger.value()
        self.parameter.defaultValueDict[
            DataType.FLOAT] = self._defaultFloat.value()
        self.parameter.defaultValueDict[
            DataType.BOOLEAN] = self._defaultBoolean.currentData()
        self.parameter.defaultValueDict[
            DataType.STRING] = self._defaultString.text()

        self.parameter.minimumInteger = self._minimumInteger.value()
        self.parameter.maximumInteger = self._maximumInteger.value()
        self.parameter.minimumFloat = self._minimumFloat.value()
        self.parameter.maximumFloat = self._maximumFloat.value()

        self.parameter.ValidateDefaultValues()

        self.SetFieldsFromParameter()