PyDragsView/SplitPanel.py

122 lines
4.3 KiB
Python
Raw Normal View History

2023-12-30 08:15:07 +00:00
import Manager
from DockPanel import DockPanel
from PyQt5.QtWidgets import QApplication, QWidget, QFrame
from enum import Enum
from PyQt5.QtCore import pyqtSignal, QPoint
from PyQt5.QtCore import QRect, Qt
from PyQt5.QtWidgets import QMainWindow
class SplitType(Enum):
SPLIT_H = 0
SPLIT_V = 1
class DragSplitter(QFrame):
adjustSignal = pyqtSignal(QPoint)
def __init__(self, split:SplitType, parent:QWidget):
super(DragSplitter, self).__init__(parent)
self.setFrameShape(QFrame.Shape.WinPanel)
self.setFrameShadow(QFrame.Shadow.Raised)
if split == SplitType.SPLIT_H:
self.setCursor(Qt.CursorShape.SplitHCursor)
else:
self.setCursor(Qt.CursorShape.SplitVCursor)
pass
def mouseMoveEvent(self, a0):
super().mouseMoveEvent(a0)
up_point = self.mapToParent(a0.pos())
self.adjustSignal.emit(up_point)
class SplitPanel(QWidget):
def __init__(self, a: DockPanel, b: DockPanel, split: SplitType, parent:QWidget = None):
super(SplitPanel, self).__init__(parent)
self.splitter_widget = DragSplitter(split, self)
self.splitter_widget.adjustSignal[QPoint].connect(self.__splitter_adjust)
self.split_member = (a, b)
self.split_member[0].setParent(self)
self.split_member[1].setParent(self)
self.split_info = (split, 0.5, 7)
self.sync_status()
pass
def __view_list(self) -> [DockPanel]:
retval: [DockPanel] = [self.split_member[0], self.split_member[1]]
return retval
def set_split_info(self, o: SplitType, pos: float, width: float = 8):
self.split_info = (o, pos, width)
self.sync_status()
def sync_status(self):
if self.split_info[0] == SplitType.SPLIT_H:
total_width = self.width()
width_a = total_width * self.split_info[1]
width_b = total_width - width_a - self.split_info[2]
self.split_member[0].setGeometry(0, 0, int(width_a), self.height())
self.split_member[1].setGeometry(int(width_a + self.split_info[2]), 0, int(width_b), self.height())
handle_rect = QRect(int(width_a), 0, int(self.split_info[2]), self.height())
self.splitter_widget.setGeometry(handle_rect)
else:
total_height = self.height()
height_a = total_height * self.split_info[1]
height_b = total_height - height_a - self.split_info[2]
self.split_member[0].setGeometry(0, 0, self.width(), int(height_a))
self.split_member[1].setGeometry(0, int(height_a + self.split_info[2]) - 1, self.width(), int(height_b) + 1)
handle_rect = QRect(0, int(height_a), self.width(), int(self.split_info[2]))
self.splitter_widget.setGeometry(handle_rect)
pass
def resizeEvent(self, a0):
super().resizeEvent(a0)
self.sync_status()
def __splitter_adjust(self, pos: QPoint):
if self.split_info[0] == SplitType.SPLIT_H:
leftw = self.split_member[0].minimumWidth()
rightw = self.split_member[1].minimumWidth()
if (pos.x() >= leftw) and (pos.x() <= self.width() - rightw):
self.split_info = (self.split_info[0], pos.x() / self.width(), self.split_info[2])
else:
toph = self.split_member[0].minimumHeight()
bottomh = self.split_member[1].minimumHeight()
if (pos.y() >= toph) and (pos.y() <= self.height() - bottomh):
self.split_info = (self.split_info[0], pos.y() / self.height(), self.split_info[2])
self.sync_status()
def replace_view(self, new: DockPanel, old: DockPanel):
if old in self.__view_list() and new not in self.__view_list():
if self.split_member[0] == old:
self.split_member = (new, self.split_member[1], self.split_member[2])
else:
self.split_member = (self.split_member[0], new, self.split_member[2])
old.setParent(None)
self.sync_status()
pass
if __name__ == "__main__":
app = QApplication([])
ow = QMainWindow()
app.installEventFilter(Manager.DragManager.instance())
a = DockPanel("docka", None, None)
b = DockPanel("dockb", None, None)
win = SplitPanel(a, b, SplitType.SPLIT_H)
ow.setCentralWidget(win)
ow.show()
app.exec()