handOver2/ui/components/splitter.py

149 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
"""
커스텀 분리바 모듈
드래그로 크기를 조절할 수 있는 분리바를 정의합니다.
"""
from PySide6.QtWidgets import QSplitter, QSplitterHandle, QWidget
from PySide6.QtCore import Qt
from PySide6.QtGui import QPainter, QColor, QPen
from core.config import ConfigManager
from core.logger import get_logger
logger = get_logger(__name__)
class CustomSplitterHandle(QSplitterHandle):
"""
커스텀 분리바 핸들
드래그 가능한 분리바 핸들입니다.
중앙에 점 표시를 제공합니다.
"""
def __init__(self, orientation, parent):
super().__init__(orientation, parent)
self.config = ConfigManager()
self._is_hovered = False
def paintEvent(self, event):
"""페인트 이벤트"""
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
theme = self.config.theme
if theme == 'dark':
bg_color = "#1e293b" if not self._is_hovered else "#334155"
dot_color = "#475569" if not self._is_hovered else "#64748b"
else:
bg_color = "#f1f5f9" if not self._is_hovered else "#e2e8f0"
dot_color = "#cbd5e1" if not self._is_hovered else "#94a3b8"
# 배경
painter.fillRect(self.rect(), QColor(bg_color))
# 점 표시
painter.setPen(Qt.NoPen)
painter.setBrush(QColor(dot_color))
if self.orientation() == Qt.Horizontal:
# 수직 분리바 - 가로로 점 3개
cx = self.width() // 2
cy = self.height() // 2
for i in range(-1, 2):
painter.drawEllipse(cx - 2, cy + (i * 8) - 2, 4, 4)
else:
# 수평 분리바 - 세로로 점 3개
cx = self.width() // 2
cy = self.height() // 2
for i in range(-1, 2):
painter.drawEllipse(cx + (i * 8) - 2, cy - 2, 4, 4)
def enterEvent(self, event):
"""마우스 진입 이벤트"""
self._is_hovered = True
self.update()
super().enterEvent(event)
def leaveEvent(self, event):
"""마우스 이탈 이벤트"""
self._is_hovered = False
self.update()
super().leaveEvent(event)
class CustomSplitter(QSplitter):
"""
커스텀 분리바 위젯
두 위젯 사이에 드래그로 크기를 조절할 수 있는 분리바를 제공합니다.
Examples:
>>> splitter = CustomSplitter(Qt.Horizontal)
>>> splitter.addWidget(left_widget)
>>> splitter.addWidget(right_widget)
>>> splitter.setSizes([700, 300])
"""
def __init__(self, orientation=Qt.Horizontal, parent=None):
super().__init__(orientation, parent)
self.config = ConfigManager()
# 핸들 크기 설정
self.setHandleWidth(6)
# 스타일 적용
self._apply_style()
def createHandle(self):
"""핸들 생성 오버라이드"""
return CustomSplitterHandle(self.orientation(), self)
def _apply_style(self):
"""스타일 적용"""
theme = self.config.theme
if theme == 'dark':
bg = "#0f172a"
else:
bg = "#f8fafc"
self.setStyleSheet(f"""
QSplitter {{
background-color: {bg};
}}
QSplitter::handle {{
background-color: transparent;
}}
""")
def set_ratios(self, ratios: list):
"""
비율로 크기 설정
Args:
ratios: 비율 리스트 (예: [70, 30])
"""
total = self.width() if self.orientation() == Qt.Horizontal else self.height()
ratio_sum = sum(ratios)
sizes = [int(total * r / ratio_sum) for r in ratios]
self.setSizes(sizes)
def get_ratios(self) -> list:
"""현재 비율 반환"""
sizes = self.sizes()
total = sum(sizes)
if total == 0:
return [50, 50]
return [int(s * 100 / total) for s in sizes]