Skip to content

Commit

Permalink
实现设置多个客户端路径 (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zzaphkiel committed Jun 22, 2024
1 parent 1fb07c7 commit 5cd8fad
Show file tree
Hide file tree
Showing 22 changed files with 718 additions and 484 deletions.
1 change: 1 addition & 0 deletions Seraphine.pro
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ SOURCES += app/view/main_window.py \
app/components/message_box.py \
app/components/setting_cards.py \
app/components/profile_level_icon_widget.py \
app/components/multi_lol_path_setting.py \
app/lol/tools.py \

TRANSLATIONS += app/resource/i18n/Seraphine.zh_CN.ts
2 changes: 1 addition & 1 deletion app/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def isWin11():


class Config(QConfig):
lolFolder = ConfigItem("General", "LolPath", "", FolderValidator())
lolFolder = ConfigItem("General", "LolPath", [])
enableStartLolWithApp = ConfigItem("General", "EnableStartLolWithApp",
False, BoolValidator())

Expand Down
3 changes: 2 additions & 1 deletion app/common/style_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class StyleSheet(StyleSheetBase, Enum):
GAME_INFO_INTERFACE = 'game_info_interface'
AUXILIARY_INTERFACE = 'auxiliary_interface'
ARAM_FLYOUT = 'aram_flyout'
CHAMPION_SELECT_WIDGET = 'champion_select_widget'
DRAGGABLE_WIDGET = 'draggable_widget'
CHAMPIONS_SELECT_WIDGET = 'champions_select_widget'

def path(self, theme=Theme.AUTO):
theme = qconfig.theme if theme == Theme.AUTO else theme
Expand Down
6 changes: 4 additions & 2 deletions app/common/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ def getLoLPathByRegistry() -> str:
try:
with winreg.OpenKey(mainKey, subKey) as k:
installPath, _ = winreg.QueryValueEx(k, valueName)
return str(Path(f"{installPath}\TCLS").absolute()).replace("\\", "/")
path = str(Path(f"{installPath}\TCLS").absolute()
).replace("\\", "/")
return f"{path[:1].upper()}{path[1:]}"
except FileNotFoundError:
logger.warning("reg path or val does not exist.", TAG)
except WindowsError as e:
Expand Down Expand Up @@ -265,7 +267,7 @@ def getFileProperties(fname):


def getLolClientVersion():
gamePath = cfg.get(cfg.lolFolder)
gamePath = cfg.get(cfg.lolFolder)[0]

assert gamePath # 必须有, 否则就是调用逻辑有问题 -- By Hpero4

Expand Down
183 changes: 183 additions & 0 deletions app/components/draggable_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
from typing import List

from PyQt5.QtCore import (QPoint, Qt, QRect, QPropertyAnimation, QEasingCurve)
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import (QVBoxLayout, QFrame)


from app.components.animation_frame import CardWidget
from app.common.style_sheet import StyleSheet


class DraggableItem(CardWidget):
def __init__(self, parent=None):
super().__init__(parent)

self.slideAni = QPropertyAnimation(self, b'pos', self)

def sizeHint(self):
raise NotImplementedError()

def slideTo(self, y: int, duration=250):
self.slideAni.setStartValue(self.pos())
self.slideAni.setEndValue(QPoint(self.x(), y))
self.slideAni.setDuration(duration)
self.slideAni.setEasingCurve(QEasingCurve.Type.InOutQuad)

self.slideAni.start()


class ItemsDraggableWidget(QFrame):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.items: List[DraggableItem] = []

self.dragPos = QPoint()
self.isDragging = False
self.currentIndex = -1

self.vBoxLayout = QVBoxLayout(self)

self.__initLayout()
StyleSheet.DRAGGABLE_WIDGET.apply(self)

def __initLayout(self):
self.vBoxLayout.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
self.vBoxLayout.setContentsMargins(11, 11, 11, 11)
self.vBoxLayout.setSpacing(6)

def _addItem(self, item: DraggableItem):
item.pressed.connect(self.__onItemPressed)

self.items.append(item)
self.vBoxLayout.addWidget(item)

def mousePressEvent(self, e: QMouseEvent):
super().mousePressEvent(e)

if e.button() != Qt.MouseButton.LeftButton or \
not self.vBoxLayout.geometry().contains(e.pos()):
return

self.dragPos = e.pos()

def mouseMoveEvent(self, e: QMouseEvent):
super().mouseMoveEvent(e)

if not self.vBoxLayout.geometry().contains(e.pos()) or \
self.count() <= 1:
return

index = self.getCurrentIndex()
if index == -1:
return

item = self.tabItem(index)

dy = e.pos().y() - self.dragPos.y()
self.dragPos = e.pos()

if index == 0 and dy < 0 and item.y() <= 0:
return

if index == self.count() - 1 and dy > 0 and \
item.geometry().bottom() >= self.height() - 1:
return

item.move(item.x(), item.y() + dy)
self.isDragging = True

if dy < 0 and index > 0:
siblingIndex = index - 1
siblingItem = self.tabItem(siblingIndex)

if item.y() < siblingItem.geometry().center().y():
self.__swapItem(siblingIndex)

if dy > 0 and index < self.count() - 1:
siblingIndex = index + 1
siblingItem = self.tabItem(siblingIndex)

if item.geometry().bottom() > siblingItem.geometry().center().y():
self.__swapItem(siblingIndex)

def mouseReleaseEvent(self, e: QMouseEvent):
super().mouseReleaseEvent(e)

if not self.isDragging:
return

self.isDragging = False

item = self.tabItem(self.getCurrentIndex())
y = self.tabRect(self.getCurrentIndex()).y()

# duration = int(abs(item.y() - y) * 250 / item.height())
duration = 250

item.slideTo(y, duration)
item.slideAni.finished.connect(self.__adjustLayout)

self.setCurrentIndex(-1)

def _removeItem(self, item: DraggableItem):
index = self.items.index(item)

self.items.pop(index)
self.vBoxLayout.removeWidget(item)

item.deleteLater()
self.update()

def __swapItem(self, index):
items = self.items
swappedItem = self.tabItem(index)

y = self.tabRect(self.getCurrentIndex()).y()

items[self.getCurrentIndex()], items[index] = \
items[index], items[self.getCurrentIndex()]
self.setCurrentIndex(index)
swappedItem.slideTo(y)

def __adjustLayout(self):
self.sender().disconnect()

for item in self.items:
self.vBoxLayout.removeWidget(item)

for item in self.items:
self.vBoxLayout.addWidget(item)

self.repaint()

def __onItemPressed(self):
item: DraggableItem = self.sender()
item.raise_()

index = self.items.index(item)
self.setCurrentIndex(index)

def setCurrentIndex(self, index: int):
self.currentIndex = index

def getCurrentIndex(self):
return self.currentIndex

def count(self):
return len(self.items)

def tabItem(self, index: int) -> DraggableItem:
return self.items[index]

def tabRect(self, index: int) -> QRect:
y = 0

for i in range(index):
y += self.tabItem(i).height()
y += self.vBoxLayout.spacing()

rect = self.tabItem(index).geometry()
rect.moveTop(y + self.vBoxLayout.contentsMargins().top() + 1)

return rect
51 changes: 47 additions & 4 deletions app/components/message_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QLabel, QTextBrowser, QPushButton, QVBoxLayout, QWidget
from ..common.qfluentwidgets import (MessageBox, MessageBoxBase, SmoothScrollArea,
SubtitleLabel, BodyLabel, TextEdit, TitleLabel,
CheckBox, setCustomStyleSheet, ProgressBar,
PrimaryPushButton, ComboBox)
from app.common.qfluentwidgets import (MessageBox, MessageBoxBase, SmoothScrollArea,
SubtitleLabel, BodyLabel, TextEdit, TitleLabel,
CheckBox, setCustomStyleSheet, ProgressBar,
PrimaryPushButton, ComboBox)

from app.common.config import VERSION, cfg, LOCAL_PATH, BETA
from app.common.util import (github, getLolClientPidSlowly, getPortTokenServerByPid,
Expand All @@ -20,6 +20,7 @@
from app.common.update import runUpdater
from app.lol.connector import connector
from app.components.multi_champion_select import MultiChampionSelectWidget
from app.components.multi_lol_path_setting import PathDraggableWidget


class UpdateMessageBox(MessageBoxBase):
Expand Down Expand Up @@ -380,3 +381,45 @@ def __myOnYesButtonClicked(self):
def __myOnCancelButtonClicked(self):
self.reject()
self.rejected.emit()


class MultiPathSettingMsgBox(MessageBoxBase):

def __init__(self, paths: list, parent=None):
super().__init__(parent)
self.myYesButton = PrimaryPushButton(self.tr('OK'), self.buttonGroup)
self.myCancelButton = QPushButton(self.tr('Cancel'), self.buttonGroup)

self.titleLabel = TitleLabel(self.tr("Set LOL cLient path"))
self.pathsWidget = PathDraggableWidget(paths)

self.__initWidget()
self.__initLayout()

def __initLayout(self):
self.viewLayout.addWidget(self.titleLabel)
self.viewLayout.addWidget(self.pathsWidget)

self.buttonLayout.addWidget(self.myYesButton)
self.buttonLayout.addWidget(self.myCancelButton)

def __initWidget(self):
self.yesButton.setVisible(False)
self.cancelButton.setVisible(False)
self.myCancelButton.setObjectName("cancelButton")

self.myYesButton.clicked.connect(self.__myOnYesButtonClicked)
self.myCancelButton.clicked.connect(self.__myOnCancelButtonClicked)

# 强迫症 TV 之这玩意左边多出来了
self.titleLabel.setStyleSheet("padding-left: 1px")

def __myOnYesButtonClicked(self):
cfg.set(cfg.lolFolder, self.pathsWidget.getCurrentPaths())

self.accept()
self.accepted.emit()

def __myOnCancelButtonClicked(self):
self.reject()
self.rejected.emit()
Loading

0 comments on commit 5cd8fad

Please sign in to comment.