diff --git a/modules/prompt_window.py b/modules/prompt_window.py index 3c6838c..02ac453 100644 --- a/modules/prompt_window.py +++ b/modules/prompt_window.py @@ -1,5 +1,6 @@ from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget, - QTreeWidgetItem, QPushButton, QLineEdit, QLabel) + QTreeWidgetItem, QPushButton, QLineEdit, QLabel, + QScrollArea, QWidget, QCheckBox, QFrame) from PyQt6.QtCore import Qt, pyqtSignal from .prompt_categories import PROMPT_CATEGORIES @@ -10,6 +11,7 @@ class PromptWindow(QDialog): super().__init__(parent) self.setWindowTitle("Готовые промпты") self.setModal(False) + self.selected_prompts = set() self.setup_ui() self.load_categories() @@ -17,24 +19,48 @@ class PromptWindow(QDialog): self.setStyleSheet(""" QDialog { background-color: #2b2b2b; - min-width: 1000px; - min-height: 800px; + min-width: 1500px; + min-height: 700px; } - QTreeWidget { + QScrollArea { background-color: #1e1e1e; - color: #ffffff; border: 1px solid #3b3b3b; border-radius: 4px; padding: 8px; + } + QScrollArea > QWidget > QWidget { + background-color: #1e1e1e; + } + QLabel { + color: #ffffff; font-size: 14px; + font-weight: bold; + padding: 8px; + background-color: #3b3b3b; + border-radius: 4px; } - QTreeWidget::item { - padding: 6px; - min-height: 24px; + QCheckBox { + color: #ffffff; + font-size: 14px; + padding: 4px; + spacing: 8px; } - QTreeWidget::item:selected { + QCheckBox::indicator { + width: 18px; + height: 18px; + } + QCheckBox::indicator:unchecked { + border: 2px solid #555555; + background-color: #3b3b3b; + border-radius: 3px; + } + QCheckBox::indicator:checked { + border: 2px solid #0d6efd; background-color: #0d6efd; - color: white; + border-radius: 3px; + } + QCheckBox::indicator:hover { + border-color: #0b5ed7; } QPushButton { background-color: #0d6efd; @@ -60,8 +86,10 @@ class PromptWindow(QDialog): font-size: 14px; min-height: 24px; } - QLabel { - font-size: 14px; + QFrame { + background-color: #1e1e1e; + border: 1px solid #3b3b3b; + border-radius: 4px; } """) @@ -76,15 +104,22 @@ class PromptWindow(QDialog): search_layout.addWidget(self.search_input) layout.addLayout(search_layout) - # Дерево категорий - self.tree = QTreeWidget() - self.tree.setHeaderLabels(["Категории и промпты"]) - self.tree.itemDoubleClicked.connect(self.on_item_double_clicked) - layout.addWidget(self.tree) + # Горизонтальная прокрутка для категорий + categories_scroll = QScrollArea() + categories_scroll.setWidgetResizable(True) + categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn) + categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) + + categories_widget = QWidget() + self.categories_layout = QHBoxLayout(categories_widget) + self.categories_layout.setSpacing(10) + categories_scroll.setWidget(categories_widget) + + layout.addWidget(categories_scroll) # Кнопки buttons_layout = QHBoxLayout() - add_button = QPushButton("Добавить выбранное") + add_button = QPushButton("Добавить выбранные") add_button.clicked.connect(self.add_selected) close_button = QPushButton("Закрыть") close_button.clicked.connect(self.close) @@ -93,52 +128,72 @@ class PromptWindow(QDialog): layout.addLayout(buttons_layout) def load_categories(self): - """Загрузка категорий и промптов в дерево""" + """Загрузка категорий и промптов""" for category, subcategories in PROMPT_CATEGORIES.items(): - category_item = QTreeWidgetItem([category]) - self.tree.addTopLevelItem(category_item) + # Создаем фрейм для категории + category_frame = QFrame() + category_layout = QVBoxLayout(category_frame) + category_layout.setSpacing(5) + + # Добавляем заголовок категории + category_label = QLabel(category) + category_layout.addWidget(category_label) + + # Создаем скролл для подкатегорий + subcategories_scroll = QScrollArea() + subcategories_scroll.setWidgetResizable(True) + subcategories_widget = QWidget() + subcategories_layout = QVBoxLayout(subcategories_widget) for subcategory, prompts in subcategories.items(): - subcategory_item = QTreeWidgetItem([subcategory]) - category_item.addChild(subcategory_item) + # Добавляем заголовок подкатегории + subcategory_label = QLabel(subcategory) + subcategories_layout.addWidget(subcategory_label) + # Добавляем чекбоксы для промптов for prompt in prompts: - prompt_item = QTreeWidgetItem([prompt]) - subcategory_item.addChild(prompt_item) + checkbox = QCheckBox(prompt) + checkbox.stateChanged.connect(lambda state, p=prompt: self.on_checkbox_changed(state, p)) + subcategories_layout.addWidget(checkbox) + + subcategories_scroll.setWidget(subcategories_widget) + category_layout.addWidget(subcategories_scroll) + + # Добавляем категорию в горизонтальный layout + self.categories_layout.addWidget(category_frame) - self.tree.expandAll() + def on_checkbox_changed(self, state, prompt): + """Обработка изменения состояния чекбокса""" + if state == Qt.CheckState.Checked.value: + self.selected_prompts.add(prompt) + else: + self.selected_prompts.discard(prompt) def filter_prompts(self, text): """Фильтрация промптов по поисковому запросу""" text = text.lower() - self.tree.clear() - self.load_categories() - - if not text: - return - - def filter_items(item): - if item.childCount() == 0: # Это промпт - return text in item.text(0).lower() - else: # Это категория - has_visible_children = False - for i in range(item.childCount()): - if filter_items(item.child(i)): - has_visible_children = True - if not has_visible_children: - item.parent().removeChild(item) - return has_visible_children - - for i in range(self.tree.topLevelItemCount()): - filter_items(self.tree.topLevelItem(i)) - - def on_item_double_clicked(self, item): - """Обработка двойного клика по элементу""" - if item.childCount() == 0: # Если это промпт - self.prompt_selected.emit(item.text(0)) + for i in range(self.categories_layout.count()): + category_frame = self.categories_layout.itemAt(i).widget() + for j in range(category_frame.layout().count()): + widget = category_frame.layout().itemAt(j).widget() + if isinstance(widget, QScrollArea): + scroll_widget = widget.widget() + for k in range(scroll_widget.layout().count()): + sub_widget = scroll_widget.layout().itemAt(k).widget() + if isinstance(sub_widget, QCheckBox): + sub_widget.setVisible(text in sub_widget.text().lower()) + elif isinstance(sub_widget, QLabel): + # Показываем/скрываем заголовок подкатегории в зависимости от видимости его промптов + has_visible_prompts = False + for l in range(k + 1, scroll_widget.layout().count()): + next_widget = scroll_widget.layout().itemAt(l).widget() + if isinstance(next_widget, QCheckBox) and next_widget.isVisible(): + has_visible_prompts = True + break + sub_widget.setVisible(has_visible_prompts) def add_selected(self): - """Добавление выбранного промпта""" - selected_items = self.tree.selectedItems() - if selected_items and selected_items[0].childCount() == 0: - self.prompt_selected.emit(selected_items[0].text(0)) \ No newline at end of file + """Добавление выбранных промптов""" + if self.selected_prompts: + prompts_text = ", ".join(sorted(self.selected_prompts)) + self.prompt_selected.emit(prompts_text) \ No newline at end of file