97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# gui/components/kanban_board.py
|
|
|
|
"""Переиспользуемый компонент канбан-доски."""
|
|
|
|
from typing import Dict, List, Optional
|
|
|
|
from PySide6.QtCore import Signal
|
|
from PySide6.QtWidgets import QWidget
|
|
|
|
from gui.components.kanban_card import KanbanCard
|
|
from gui.components.kanban_column import KanbanColumn
|
|
from gui.containers.h_container import HContainer
|
|
from gui.containers.s_container import SContainer
|
|
|
|
|
|
class KanbanBoard(SContainer):
|
|
"""Канбан-доска из нескольких горизонтальных колонок."""
|
|
|
|
card_clicked = Signal(object)
|
|
|
|
def __init__(
|
|
self,
|
|
width_percent: Optional[int] = None,
|
|
height_percent: Optional[int] = None,
|
|
margin: int = 0,
|
|
spacing: int = 0,
|
|
parent: Optional[QWidget] = None,
|
|
):
|
|
super().__init__(
|
|
width_percent=width_percent,
|
|
height_percent=height_percent,
|
|
margin=margin,
|
|
spacing=spacing,
|
|
content_fit=True,
|
|
parent=parent,
|
|
)
|
|
self._columns: Dict[object, KanbanColumn] = {}
|
|
self._columns_order: List[object] = []
|
|
self._columns_container = HContainer(
|
|
spacing=4,
|
|
margin=[4, 4, 4, 4],
|
|
parent=self,
|
|
)
|
|
|
|
def add_column(
|
|
self,
|
|
column_id: object,
|
|
title: str,
|
|
color: str = "#DFE1E6",
|
|
width_percent: Optional[int] = None,
|
|
style: str = "KANBAN_COLUMN",
|
|
) -> KanbanColumn:
|
|
"""Добавить колонку на доску."""
|
|
column = KanbanColumn(
|
|
column_id=column_id,
|
|
title=title,
|
|
color=color,
|
|
style=style,
|
|
)
|
|
column.card_clicked.connect(self.card_clicked.emit)
|
|
self._columns[column_id] = column
|
|
self._columns_order.append(column_id)
|
|
self._columns_container.add_widget(column)
|
|
self._recompute_column_widths(width_percent)
|
|
return column
|
|
|
|
def get_column(self, column_id: object) -> Optional[KanbanColumn]:
|
|
"""Получить колонку по ID."""
|
|
return self._columns.get(column_id)
|
|
|
|
def get_columns(self) -> List[KanbanColumn]:
|
|
"""Список всех колонок в порядке добавления."""
|
|
return [self._columns[column_id] for column_id in self._columns_order]
|
|
|
|
def clear_all_cards(self) -> None:
|
|
"""Удалить все карточки из всех колонок."""
|
|
for column in self._columns.values():
|
|
column.clear_cards()
|
|
|
|
def _recompute_column_widths(self, explicit_width: Optional[int] = None) -> None:
|
|
n_columns = len(self._columns_order)
|
|
if n_columns == 0:
|
|
return
|
|
if explicit_width is not None:
|
|
for column_id in self._columns_order:
|
|
self._columns[column_id].set_percent_sizes(width_percent=explicit_width)
|
|
return
|
|
base_width = 100 // n_columns
|
|
remainder = 100 % n_columns
|
|
for index, column_id in enumerate(self._columns_order):
|
|
width = base_width + (1 if index < remainder else 0)
|
|
self._columns[column_id].set_percent_sizes(width_percent=width)
|
|
|
|
|
|
__all__ = ["KanbanBoard", "KanbanColumn", "KanbanCard"]
|