4 Commits

Author SHA1 Message Date
86b1653fe3 impr: minor improvements 2023-10-15 02:47:15 +08:00
3e2e96b00b impr: TabTools_ChartRecommend ui 2023-10-15 00:24:17 +08:00
9bb6f5b3d9 fix: ChartSelector not selecting rating class 2023-10-14 17:58:35 +08:00
8628399469 impr: TextSegmentDelegate improvements 2023-10-14 16:52:41 +08:00
9 changed files with 630 additions and 368 deletions

View File

@ -6,113 +6,15 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>668</width> <width>616</width>
<height>546</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">TabTools_ChartRecommend</string> <string notr="true">TabTools_ChartRecommend</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout">
<item> <item row="0" column="1">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>constantRangeFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="rangeFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">AA</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">EX</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">EX+</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rangeFromPlayRating_ExPlusLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ExLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="rangeFromPlayRating_AaLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
<string>chartsByConstant</string> <string>chartsByConstant</string>
@ -147,51 +49,197 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="chartsByConstant_numLabel"> <widget class="QLabel" name="chartsByConstant_numLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string notr="true">...</string> <string notr="true">...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsByConstant_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QWidget" name="widget" native="true"> <widget class="QListView" name="chartsByConstant_modelView">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="chartsByConstant_gridLayout"/> <property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>constantRangeFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="rangeFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">EX+</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ExPlusLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">EX</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ExLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">AA</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="rangeFromPlayRating_AaLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string notr="true">A</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ALabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string notr="true">B</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="rangeFromPlayRating_BLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string notr="true">C</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="rangeFromPlayRating_CLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
<string>chartsRecommendFromPlayRating</string> <string>chartsRecommendFromPlayRating</string>
@ -246,45 +294,48 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="chartsRecommendFromPlayRating_numLabel"> <widget class="QLabel" name="chartsRecommendFromPlayRating_numLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string notr="true">...</string> <string notr="true">...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsRecommendFromPlayRating_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QWidget" name="widget_2" native="true"> <widget class="QTableView" name="chartsRecommendFromPlayRating_modelView">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="chartsRecommendFromPlayRating_gridLayout"/> <property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -15,82 +15,19 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon, QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter, QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform) QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QGridLayout, QGroupBox, from PySide6.QtWidgets import (QAbstractItemView, QApplication, QDoubleSpinBox, QFormLayout,
QHBoxLayout, QLabel, QPushButton, QSizePolicy, QGridLayout, QGroupBox, QHBoxLayout, QHeaderView,
QSpacerItem, QVBoxLayout, QWidget) QLabel, QListView, QSizePolicy, QTableView,
QVBoxLayout, QWidget)
class Ui_TabTools_ChartRecommend(object): class Ui_TabTools_ChartRecommend(object):
def setupUi(self, TabTools_ChartRecommend): def setupUi(self, TabTools_ChartRecommend):
if not TabTools_ChartRecommend.objectName(): if not TabTools_ChartRecommend.objectName():
TabTools_ChartRecommend.setObjectName(u"TabTools_ChartRecommend") TabTools_ChartRecommend.setObjectName(u"TabTools_ChartRecommend")
TabTools_ChartRecommend.resize(668, 546) TabTools_ChartRecommend.resize(616, 500)
TabTools_ChartRecommend.setWindowTitle(u"TabTools_ChartRecommend") TabTools_ChartRecommend.setWindowTitle(u"TabTools_ChartRecommend")
self.verticalLayout = QVBoxLayout(TabTools_ChartRecommend) self.gridLayout = QGridLayout(TabTools_ChartRecommend)
self.verticalLayout.setObjectName(u"verticalLayout") self.gridLayout.setObjectName(u"gridLayout")
self.groupBox = QGroupBox(TabTools_ChartRecommend)
self.groupBox.setObjectName(u"groupBox")
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.rangeFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox)
self.rangeFromPlayRating_playRatingSpinBox.setObjectName(u"rangeFromPlayRating_playRatingSpinBox")
self.rangeFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.rangeFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.rangeFromPlayRating_playRatingSpinBox.setDecimals(3)
self.rangeFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.rangeFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.verticalLayout_2.addWidget(self.rangeFromPlayRating_playRatingSpinBox)
self.gridLayout_3 = QGridLayout()
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.label_3 = QLabel(self.groupBox)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"AA")
self.label_3.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_3, 0, 2, 1, 1)
self.label_2 = QLabel(self.groupBox)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"EX")
self.label_2.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_2, 0, 1, 1, 1)
self.label = QLabel(self.groupBox)
self.label.setObjectName(u"label")
self.label.setText(u"EX+")
self.label.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1)
self.rangeFromPlayRating_ExPlusLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExPlusLabel.setObjectName(u"rangeFromPlayRating_ExPlusLabel")
self.rangeFromPlayRating_ExPlusLabel.setText(u"...")
self.rangeFromPlayRating_ExPlusLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExPlusLabel, 1, 0, 1, 1)
self.rangeFromPlayRating_ExLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExLabel.setObjectName(u"rangeFromPlayRating_ExLabel")
self.rangeFromPlayRating_ExLabel.setText(u"...")
self.rangeFromPlayRating_ExLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExLabel, 1, 1, 1, 1)
self.rangeFromPlayRating_AaLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_AaLabel.setObjectName(u"rangeFromPlayRating_AaLabel")
self.rangeFromPlayRating_AaLabel.setText(u"...")
self.rangeFromPlayRating_AaLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_AaLabel, 1, 2, 1, 1)
self.verticalLayout_2.addLayout(self.gridLayout_3)
self.verticalLayout.addWidget(self.groupBox)
self.groupBox_2 = QGroupBox(TabTools_ChartRecommend) self.groupBox_2 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_2.setObjectName(u"groupBox_2") self.groupBox_2.setObjectName(u"groupBox_2")
self.verticalLayout_3 = QVBoxLayout(self.groupBox_2) self.verticalLayout_3 = QVBoxLayout(self.groupBox_2)
@ -109,37 +46,137 @@ class Ui_TabTools_ChartRecommend(object):
self.chartsByConstant_numLabel = QLabel(self.groupBox_2) self.chartsByConstant_numLabel = QLabel(self.groupBox_2)
self.chartsByConstant_numLabel.setObjectName(u"chartsByConstant_numLabel") self.chartsByConstant_numLabel.setObjectName(u"chartsByConstant_numLabel")
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.chartsByConstant_numLabel.sizePolicy().hasHeightForWidth())
self.chartsByConstant_numLabel.setSizePolicy(sizePolicy)
self.chartsByConstant_numLabel.setText(u"...") self.chartsByConstant_numLabel.setText(u"...")
self.horizontalLayout_3.addWidget(self.chartsByConstant_numLabel) self.horizontalLayout_3.addWidget(self.chartsByConstant_numLabel)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(self.horizontalSpacer)
self.chartsByConstant_refreshButton = QPushButton(self.groupBox_2)
self.chartsByConstant_refreshButton.setObjectName(u"chartsByConstant_refreshButton")
self.chartsByConstant_refreshButton.setEnabled(False)
self.horizontalLayout_3.addWidget(self.chartsByConstant_refreshButton)
self.verticalLayout_3.addLayout(self.horizontalLayout_3) self.verticalLayout_3.addLayout(self.horizontalLayout_3)
self.widget = QWidget(self.groupBox_2) self.chartsByConstant_modelView = QListView(self.groupBox_2)
self.widget.setObjectName(u"widget") self.chartsByConstant_modelView.setObjectName(u"chartsByConstant_modelView")
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy1.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy1.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth()) sizePolicy1.setHeightForWidth(self.chartsByConstant_modelView.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy) self.chartsByConstant_modelView.setSizePolicy(sizePolicy1)
self.chartsByConstant_gridLayout = QGridLayout(self.widget) self.chartsByConstant_modelView.setMinimumSize(QSize(150, 0))
self.chartsByConstant_gridLayout.setObjectName(u"chartsByConstant_gridLayout") self.chartsByConstant_modelView.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.chartsByConstant_modelView.setSelectionMode(QAbstractItemView.NoSelection)
self.chartsByConstant_modelView.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
self.chartsByConstant_modelView.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self.verticalLayout_3.addWidget(self.widget) self.verticalLayout_3.addWidget(self.chartsByConstant_modelView)
self.verticalLayout.addWidget(self.groupBox_2) self.gridLayout.addWidget(self.groupBox_2, 0, 1, 1, 1)
self.groupBox = QGroupBox(TabTools_ChartRecommend)
self.groupBox.setObjectName(u"groupBox")
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.rangeFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox)
self.rangeFromPlayRating_playRatingSpinBox.setObjectName(u"rangeFromPlayRating_playRatingSpinBox")
self.rangeFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.rangeFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.rangeFromPlayRating_playRatingSpinBox.setDecimals(3)
self.rangeFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.rangeFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.verticalLayout_2.addWidget(self.rangeFromPlayRating_playRatingSpinBox)
self.formLayout = QFormLayout()
self.formLayout.setObjectName(u"formLayout")
self.formLayout.setLabelAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.formLayout.setFormAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
self.label = QLabel(self.groupBox)
self.label.setObjectName(u"label")
self.label.setText(u"EX+")
self.label.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
self.rangeFromPlayRating_ExPlusLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExPlusLabel.setObjectName(u"rangeFromPlayRating_ExPlusLabel")
self.rangeFromPlayRating_ExPlusLabel.setText(u"...")
self.rangeFromPlayRating_ExPlusLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.formLayout.setWidget(0, QFormLayout.FieldRole, self.rangeFromPlayRating_ExPlusLabel)
self.label_2 = QLabel(self.groupBox)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"EX")
self.label_2.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
self.rangeFromPlayRating_ExLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExLabel.setObjectName(u"rangeFromPlayRating_ExLabel")
self.rangeFromPlayRating_ExLabel.setText(u"...")
self.rangeFromPlayRating_ExLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.formLayout.setWidget(1, QFormLayout.FieldRole, self.rangeFromPlayRating_ExLabel)
self.label_3 = QLabel(self.groupBox)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"AA")
self.label_3.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3)
self.rangeFromPlayRating_AaLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_AaLabel.setObjectName(u"rangeFromPlayRating_AaLabel")
self.rangeFromPlayRating_AaLabel.setText(u"...")
self.rangeFromPlayRating_AaLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.formLayout.setWidget(2, QFormLayout.FieldRole, self.rangeFromPlayRating_AaLabel)
self.label_5 = QLabel(self.groupBox)
self.label_5.setObjectName(u"label_5")
self.label_5.setText(u"A")
self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_5)
self.rangeFromPlayRating_ALabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ALabel.setObjectName(u"rangeFromPlayRating_ALabel")
self.rangeFromPlayRating_ALabel.setText(u"...")
self.formLayout.setWidget(3, QFormLayout.FieldRole, self.rangeFromPlayRating_ALabel)
self.label_8 = QLabel(self.groupBox)
self.label_8.setObjectName(u"label_8")
self.label_8.setText(u"B")
self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_8)
self.rangeFromPlayRating_BLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_BLabel.setObjectName(u"rangeFromPlayRating_BLabel")
self.rangeFromPlayRating_BLabel.setText(u"...")
self.formLayout.setWidget(4, QFormLayout.FieldRole, self.rangeFromPlayRating_BLabel)
self.label_10 = QLabel(self.groupBox)
self.label_10.setObjectName(u"label_10")
self.label_10.setText(u"C")
self.formLayout.setWidget(5, QFormLayout.LabelRole, self.label_10)
self.rangeFromPlayRating_CLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_CLabel.setObjectName(u"rangeFromPlayRating_CLabel")
self.rangeFromPlayRating_CLabel.setText(u"...")
self.formLayout.setWidget(5, QFormLayout.FieldRole, self.rangeFromPlayRating_CLabel)
self.verticalLayout_2.addLayout(self.formLayout)
self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
self.groupBox_3 = QGroupBox(TabTools_ChartRecommend) self.groupBox_3 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_3.setObjectName(u"groupBox_3") self.groupBox_3.setObjectName(u"groupBox_3")
@ -173,34 +210,33 @@ class Ui_TabTools_ChartRecommend(object):
self.chartsRecommendFromPlayRating_numLabel = QLabel(self.groupBox_3) self.chartsRecommendFromPlayRating_numLabel = QLabel(self.groupBox_3)
self.chartsRecommendFromPlayRating_numLabel.setObjectName(u"chartsRecommendFromPlayRating_numLabel") self.chartsRecommendFromPlayRating_numLabel.setObjectName(u"chartsRecommendFromPlayRating_numLabel")
sizePolicy.setHeightForWidth(self.chartsRecommendFromPlayRating_numLabel.sizePolicy().hasHeightForWidth())
self.chartsRecommendFromPlayRating_numLabel.setSizePolicy(sizePolicy)
self.chartsRecommendFromPlayRating_numLabel.setText(u"...") self.chartsRecommendFromPlayRating_numLabel.setText(u"...")
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_numLabel) self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_numLabel)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(self.horizontalSpacer_2)
self.chartsRecommendFromPlayRating_refreshButton = QPushButton(self.groupBox_3)
self.chartsRecommendFromPlayRating_refreshButton.setObjectName(u"chartsRecommendFromPlayRating_refreshButton")
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(False)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_refreshButton)
self.verticalLayout_4.addLayout(self.horizontalLayout_2) self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.widget_2 = QWidget(self.groupBox_3) self.chartsRecommendFromPlayRating_modelView = QTableView(self.groupBox_3)
self.widget_2.setObjectName(u"widget_2") self.chartsRecommendFromPlayRating_modelView.setObjectName(u"chartsRecommendFromPlayRating_modelView")
sizePolicy.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth()) sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.widget_2.setSizePolicy(sizePolicy) sizePolicy2.setHorizontalStretch(0)
self.chartsRecommendFromPlayRating_gridLayout = QGridLayout(self.widget_2) sizePolicy2.setVerticalStretch(0)
self.chartsRecommendFromPlayRating_gridLayout.setObjectName(u"chartsRecommendFromPlayRating_gridLayout") sizePolicy2.setHeightForWidth(self.chartsRecommendFromPlayRating_modelView.sizePolicy().hasHeightForWidth())
self.chartsRecommendFromPlayRating_modelView.setSizePolicy(sizePolicy2)
self.chartsRecommendFromPlayRating_modelView.setMinimumSize(QSize(200, 0))
self.chartsRecommendFromPlayRating_modelView.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.chartsRecommendFromPlayRating_modelView.setSelectionMode(QAbstractItemView.SingleSelection)
self.chartsRecommendFromPlayRating_modelView.setSelectionBehavior(QAbstractItemView.SelectRows)
self.chartsRecommendFromPlayRating_modelView.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
self.chartsRecommendFromPlayRating_modelView.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
self.verticalLayout_4.addWidget(self.widget_2) self.verticalLayout_4.addWidget(self.chartsRecommendFromPlayRating_modelView)
self.verticalLayout.addWidget(self.groupBox_3) self.gridLayout.addWidget(self.groupBox_3, 1, 0, 1, 2)
self.retranslateUi(TabTools_ChartRecommend) self.retranslateUi(TabTools_ChartRecommend)
@ -209,11 +245,9 @@ class Ui_TabTools_ChartRecommend(object):
# setupUi # setupUi
def retranslateUi(self, TabTools_ChartRecommend): def retranslateUi(self, TabTools_ChartRecommend):
self.groupBox.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"constantRangeFromPlayRating", None))
self.groupBox_2.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsByConstant", None)) self.groupBox_2.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsByConstant", None))
self.chartsByConstant_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None)) self.groupBox.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"constantRangeFromPlayRating", None))
self.groupBox_3.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsRecommendFromPlayRating", None)) self.groupBox_3.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsRecommendFromPlayRating", None))
self.chartsRecommendFromPlayRating_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None))
pass pass
# retranslateUi # retranslateUi

View File

@ -25,12 +25,28 @@ class TextSegmentDelegate(QStyledItemDelegate):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
# TODO: make this differ by index self.baseXOffsets: dict[str, int] = {}
self.baseXOffset = 0 self.baseYOffsets: dict[str, int] = {}
self.baseYOffset = 0
self.verticalAlign = TextSegmentDelegateVerticalAlign.Middle self.verticalAlign = TextSegmentDelegateVerticalAlign.Middle
def indexOffsetKey(self, index: QModelIndex):
return f"{index.row()},{index.column()}"
def setBaseXOffset(self, index: QModelIndex, offset: int):
key = self.indexOffsetKey(index)
if not offset:
self.baseXOffsets.pop(key, None)
else:
self.baseXOffsets[key] = offset
def setBaseYOffset(self, index: QModelIndex, offset: int):
key = self.indexOffsetKey(index)
if not offset:
self.baseYOffsets.pop(key, None)
else:
self.baseYOffsets[key] = offset
def setVerticalAlign(self, align: Literal["top", "middle", "bottom"]): def setVerticalAlign(self, align: Literal["top", "middle", "bottom"]):
if not isinstance(align, str) and align not in ["top", "middle", "bottom"]: if not isinstance(align, str) and align not in ["top", "middle", "bottom"]:
raise ValueError( raise ValueError(
@ -60,12 +76,14 @@ class TextSegmentDelegate(QStyledItemDelegate):
]: ]:
return [] return []
def sizeHint(self, option, index) -> QSize: def textsSizeHint(self, option: QStyleOptionViewItem, index: QModelIndex) -> QSize:
width = 0 width = 0
height = self.VerticalPadding height = 0
fm: QFontMetrics = option.fontMetrics fm: QFontMetrics = option.fontMetrics
for line in self.getTextSegments(index, option): segments = self.getTextSegments(index, option)
lineWidth = 4 * self.HorizontalPadding for i in range(len(segments)):
line = segments[i]
lineWidth = 2 * self.HorizontalPadding
lineHeight = 0 lineHeight = 0
for textFrag in line: for textFrag in line:
font = textFrag.get(self.FontRole) font = textFrag.get(self.FontRole)
@ -76,14 +94,30 @@ class TextSegmentDelegate(QStyledItemDelegate):
lineWidth += textWidth lineWidth += textWidth
lineHeight = max(lineHeight, textHeight) lineHeight = max(lineHeight, textHeight)
width = max(lineWidth, width) width = max(lineWidth, width)
height += lineHeight + self.VerticalPadding height += lineHeight
if i != len(segments) - 1:
height += self.VerticalPadding
return QSize(width, height) return QSize(width, height)
def sizeHint(self, option: QStyleOptionViewItem, index: QModelIndex) -> QSize:
width = self.HorizontalPadding * 2
height = self.VerticalPadding * 2
textsSizeHint = self.textsSizeHint(option, index)
return QSize(textsSizeHint.width() + width, textsSizeHint.height() + height)
def baseX(self, option: QStyleOptionViewItem, index: QModelIndex): def baseX(self, option: QStyleOptionViewItem, index: QModelIndex):
return option.rect.x() + self.HorizontalPadding + self.baseXOffset return (
option.rect.x()
+ self.HorizontalPadding
+ self.baseXOffsets.get(self.indexOffsetKey(index), 0)
)
def baseY(self, option: QStyleOptionViewItem, index: QModelIndex): def baseY(self, option: QStyleOptionViewItem, index: QModelIndex):
baseY = option.rect.y() + self.VerticalPadding + self.baseYOffset baseY = (
option.rect.y()
+ self.VerticalPadding
+ self.baseYOffsets.get(self.indexOffsetKey(index), 0)
)
if self.verticalAlign != TextSegmentDelegateVerticalAlign.Top: if self.verticalAlign != TextSegmentDelegateVerticalAlign.Top:
paintAreaSize: QSize = option.rect.size() paintAreaSize: QSize = option.rect.size()
delegateSize = self.sizeHint(option, index) delegateSize = self.sizeHint(option, index)
@ -94,7 +128,11 @@ class TextSegmentDelegate(QStyledItemDelegate):
return baseY return baseY
def textMaxWidth(self, option: QStyleOptionViewItem, index: QModelIndex): def textMaxWidth(self, option: QStyleOptionViewItem, index: QModelIndex):
return option.rect.width() - (2 * self.HorizontalPadding) - self.baseXOffset return (
option.rect.width()
- (2 * self.HorizontalPadding)
- self.baseXOffsets.get(self.indexOffsetKey(index), 0)
)
def paint( def paint(
self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex

View File

@ -1,7 +1,7 @@
from arcaea_offline.models import Chart, Difficulty, Song from arcaea_offline.models import Chart, Difficulty, Song
from arcaea_offline.utils.rating import rating_class_to_short_text, rating_class_to_text from arcaea_offline.utils.rating import rating_class_to_short_text, rating_class_to_text
from PIL import Image from PIL import Image
from PySide6.QtCore import QModelIndex, Qt, Signal from PySide6.QtCore import QModelIndex, QRect, Qt, Signal
from PySide6.QtGui import QColor, QPainter, QPixmap from PySide6.QtGui import QColor, QPainter, QPixmap
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QFrame, QFrame,
@ -138,7 +138,7 @@ class ChartDelegate(TextSegmentDelegate):
ratingClass = None ratingClass = None
ratingText = ( ratingText = (
f"{rating_class_to_text(chart.rating_class)} {chartConstantString}" f"{rating_class_to_text(ratingClass)} {chartConstantString}"
if ratingClass is not None if ratingClass is not None
else "Unknown ?" else "Unknown ?"
) )
@ -173,7 +173,9 @@ class ChartDelegate(TextSegmentDelegate):
def sizeHint(self, option, index): def sizeHint(self, option, index):
size = super().sizeHint(option, index) size = super().sizeHint(option, index)
size.setWidth(size.width() + self.HorizontalPadding + size.height()) minWidth = size.height() + 2 * self.HorizontalPadding # jacket size
width = size.width() + self.HorizontalPadding + size.height()
size.setWidth(max(minWidth, width))
return size return size
def paint(self, painter, option, index): def paint(self, painter, option, index):
@ -193,12 +195,13 @@ class ChartDelegate(TextSegmentDelegate):
jacketPath = "__TEXT_ONLY__" jacketPath = "__TEXT_ONLY__"
if jacketPath == "__TEXT_ONLY__": if jacketPath == "__TEXT_ONLY__":
self.setBaseXOffset(index, 0)
super().paint(painter, option, index) super().paint(painter, option, index)
return return
textSizeHint = super().sizeHint(option, index) textsSizeHint = super().textsSizeHint(option, index)
jacketSize = textSizeHint.height() jacketSize = textsSizeHint.height()
self.baseXOffset = self.HorizontalPadding + jacketSize self.setBaseXOffset(index, self.HorizontalPadding + jacketSize)
jacketSizeTuple = (jacketSize, jacketSize) jacketSizeTuple = (jacketSize, jacketSize)
if jacketPath: if jacketPath:
@ -214,11 +217,21 @@ class ChartDelegate(TextSegmentDelegate):
.toqpixmap() .toqpixmap()
) )
pixmapAvailableWidth = option.rect.width() - self.HorizontalPadding
pixmapAvailableHeight = option.rect.height()
if pixmapAvailableWidth < jacketSize or pixmapAvailableHeight < jacketSize:
cropRect = QRect(0, 0, pixmapAvailableWidth, pixmapAvailableHeight)
pixmap = pixmap.copy(cropRect)
painter.save() painter.save()
painter.setRenderHint(QPainter.RenderHint.LosslessImageRendering, True) painter.setRenderHint(QPainter.RenderHint.LosslessImageRendering, True)
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True) painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
pixmapBaseY = self.baseY(option, index)
painter.drawPixmap( painter.drawPixmap(
option.rect.x() + self.HorizontalPadding, self.baseY(option, index), pixmap option.rect.x() + self.HorizontalPadding,
pixmapBaseY,
pixmap,
) )
painter.restore() painter.restore()
super().paint(painter, option, index) super().paint(painter, option, index)

View File

@ -1,5 +1,5 @@
from arcaea_offline.calculate import calculate_score_range from arcaea_offline.calculate import calculate_score_range
from arcaea_offline.models import Chart, Score from arcaea_offline.models import Chart, Score, ScoreBest
from arcaea_offline.utils.rating import rating_class_to_text from arcaea_offline.utils.rating import rating_class_to_text
from arcaea_offline.utils.score import ( from arcaea_offline.utils.score import (
clear_type_to_text, clear_type_to_text,
@ -78,18 +78,21 @@ class ScoreDelegate(TextSegmentDelegate):
createGradeGradientWrapper(QColor("#5d1d35"), QColor("#9f3c55")), createGradeGradientWrapper(QColor("#5d1d35"), QColor("#9f3c55")),
] ]
def getScore(self, index: QModelIndex) -> Score | None: def getScore(self, index: QModelIndex) -> Score | ScoreBest | None:
return None return None
def getChart(self, index: QModelIndex) -> Chart | None: def getChart(self, index: QModelIndex) -> Chart | None:
return None return None
def isScoreInstance(self, index: QModelIndex) -> bool:
return isinstance(self.getScore(index), (Score, ScoreBest))
def getScoreValidateOk(self, index: QModelIndex) -> bool | None: def getScoreValidateOk(self, index: QModelIndex) -> bool | None:
score = self.getScore(index) score = self.getScore(index)
chart = self.getChart(index) chart = self.getChart(index)
if ( if (
isinstance(score, Score) self.isScoreInstance(index)
and isinstance(chart, Chart) and isinstance(chart, Chart)
and chart.notes is not None and chart.notes is not None
and score.pure is not None and score.pure is not None
@ -104,11 +107,11 @@ class ScoreDelegate(TextSegmentDelegate):
def getTextSegments(self, index, option): def getTextSegments(self, index, option):
score = self.getScore(index) score = self.getScore(index)
if not isinstance(score, Score): if not self.isScoreInstance(index):
return [ return [
[ [
{ {
self.TextRole: "Chart/Score Invalid", self.TextRole: "Score Invalid",
self.ColorRole: QColor("#ff0000"), self.ColorRole: QColor("#ff0000"),
} }
] ]
@ -199,7 +202,7 @@ class ScoreDelegate(TextSegmentDelegate):
score = self.getScore(index) score = self.getScore(index)
chart = self.getChart(index) chart = self.getChart(index)
if ( if (
isinstance(score, Score) self.isScoreInstance(index)
and isinstance(chart, Chart) and isinstance(chart, Chart)
and self.paintWarningBackground(index) and self.paintWarningBackground(index)
): ):
@ -239,7 +242,7 @@ class ScoreDelegate(TextSegmentDelegate):
else: else:
editor.setWindowTitle("-") editor.setWindowTitle("-")
if isinstance(score, Score): if self.isScoreInstance(index):
editor.setText(score) editor.setText(score)
editor.setValidateBeforeAccept(False) editor.setValidateBeforeAccept(False)
@ -260,7 +263,7 @@ class ScoreDelegate(TextSegmentDelegate):
chart = self.getChart(index) chart = self.getChart(index)
if isinstance(chart, Chart): if isinstance(chart, Chart):
editor.setChart(chart) editor.setChart(chart)
if isinstance(score, Score): if self.isScoreInstance(index):
editor.setValue(score) editor.setValue(score)
def confirmSetModelData(self, editor: ScoreEditorDelegateWrapper): def confirmSetModelData(self, editor: ScoreEditorDelegateWrapper):

View File

@ -0,0 +1,120 @@
import re
from typing import Any
from arcaea_offline.database import Database
from arcaea_offline.models import Chart, ScoreBest
from arcaea_offline.utils.rating import rating_class_to_text
from PySide6.QtCore import QAbstractListModel, QModelIndex, Qt
from PySide6.QtGui import QStandardItem, QStandardItemModel
from ui.extends.shared.delegates.chartDelegate import ChartDelegate
from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate
class ChartsModel(QAbstractListModel):
ChartRole = Qt.ItemDataRole.UserRole
def __init__(self, parent=None):
super().__init__(parent)
self.__data: list[dict[int, Any]] = []
def rowCount(self, *args) -> int:
return len(self.__data)
def columnCount(self, *args) -> int:
return 1
def headerData(self, *args):
return None
def data(self, index: QModelIndex, role: int):
if not self.checkIndex(index):
return None
return self.__data[index.row()].get(role, None)
def clear(self):
self.beginResetModel()
self.beginRemoveRows(QModelIndex(), 0, self.rowCount())
self.__data.clear()
self.endRemoveRows()
self.endResetModel()
def setCharts(self, charts: list[Chart]):
self.clear()
db = Database()
self.beginInsertRows(QModelIndex(), 0, len(charts))
for chart in charts:
pack = db.get_pack(chart.set)
if re.search(r"_append_.*$", pack.id):
basePackId = re.sub(r"_append_.*$", "", pack.id)
basePackName = db.get_pack(basePackId).name
packName = f"{basePackName} - {pack.name}"
else:
packName = pack.name
tooltip = (
f"{chart.title}@{packName} [{rating_class_to_text(chart.rating_class)}]"
)
self.__data.append(
{
Qt.ItemDataRole.ToolTipRole: tooltip,
self.ChartRole: chart,
}
)
self.endInsertRows()
class CustomChartDelegate(ChartDelegate):
def getChart(self, index: QModelIndex) -> Chart | None:
return index.data(ChartsModel.ChartRole)
class ChartsWithScoreBestModel(QStandardItemModel):
ChartRole = Qt.ItemDataRole.UserRole
ScoreBestRole = Qt.ItemDataRole.UserRole + 10
def columnCount(self, *args) -> int:
return 3
def headerData(self, *args):
return None
def setChartAndScore(self, charts: list[Chart], scoreBests: list[ScoreBest]):
self.clear()
db = Database()
self.beginInsertRows(QModelIndex(), 0, len(charts))
for chart, scoreBest in zip(charts, scoreBests):
pack = db.get_pack(chart.set)
if re.search(r"_append_.*$", pack.id):
basePackId = re.sub(r"_append_.*$", "", pack.id)
basePackName = db.get_pack(basePackId).name
packName = f"{basePackName} - {pack.name}"
else:
packName = pack.name
tooltip = (
f"{chart.title}@{packName} [{rating_class_to_text(chart.rating_class)}]\n"
f"{scoreBest.score} > {scoreBest.potential}"
)
chartItem = QStandardItem()
chartItem.setData(tooltip, Qt.ItemDataRole.ToolTipRole)
chartItem.setData(chart, self.ChartRole)
scoreBestItem = QStandardItem()
scoreBestItem.setData(tooltip, Qt.ItemDataRole.ToolTipRole)
scoreBestItem.setData(scoreBest, self.ScoreBestRole)
potentialTextItem = QStandardItem()
potentialTextItem.setText(f"{scoreBest.potential}")
self.appendRow([chartItem, scoreBestItem, potentialTextItem])
class CustomScoreBestDelegate(ScoreDelegate):
def getScore(self, index: QModelIndex):
return index.data(ChartsWithScoreBestModel.ScoreBestRole)

View File

@ -27,6 +27,9 @@ class ChartSelector(Ui_ChartSelector, QWidget):
self.valueChanged.connect(self.updateResultLabel) self.valueChanged.connect(self.updateResultLabel)
self.songIdSelector.valueChanged.connect(self.updateRatingClassEnabled) self.songIdSelector.valueChanged.connect(self.updateRatingClassEnabled)
self.songIdSelector.quickSearchActivated.connect(
self.__songIdSelectedQuickSearchActivated
)
self.songIdSelector.valueChanged.connect(self.valueChanged) self.songIdSelector.valueChanged.connect(self.valueChanged)
self.ratingClassSelector.valueChanged.connect(self.valueChanged) self.ratingClassSelector.valueChanged.connect(self.valueChanged)
@ -85,15 +88,17 @@ class ChartSelector(Ui_ChartSelector, QWidget):
texts = [" | ".join(t) for t in texts] texts = [" | ".join(t) for t in texts]
text = f'{texts[0]}<br><font color="gray">{texts[1]}</font>' text = f'{texts[0]}<br><font color="gray">{texts[1]}</font>'
else: else:
text = f'No chart data<br><font color="gray">{chart.set} | {chart.song_id} | {chart.rating_class}</font>' text = (
"No chart data<br>"
f'<font color="gray">{chart.set} | {chart.song_id} | {chart.rating_class}</font>'
)
self.resultLabel.setText(text) self.resultLabel.setText(text)
else: else:
self.resultLabel.setText("...") self.resultLabel.setText("...")
def updateRatingClassEnabled(self): def updateRatingClassEnabled(self):
ratingClasses = [] ratingClasses = []
songId = self.songIdSelector.songId() if songId := self.songIdSelector.songId():
if songId:
if self.songIdSelector.mode == SongIdSelectorMode.Chart: if self.songIdSelector.mode == SongIdSelectorMode.Chart:
items = self.db.get_charts_by_song_id(songId) items = self.db.get_charts_by_song_id(songId)
else: else:
@ -106,9 +111,8 @@ class ChartSelector(Ui_ChartSelector, QWidget):
self.songIdSelector.reset() self.songIdSelector.reset()
def selectChart(self, chart: Chart): def selectChart(self, chart: Chart):
if not self.songIdSelector.selectPack(chart.set): self.songIdSelector.selectChart(chart)
return False self.ratingClassSelector.select(chart.rating_class)
if not self.songIdSelector.selectSongId(chart.song_id):
return False def __songIdSelectedQuickSearchActivated(self, chart: Chart):
self.ratingClassSelector.select(chart.rating_class) self.ratingClassSelector.select(chart.rating_class)
return True

View File

@ -23,6 +23,7 @@ class SongIdSelectorMode(IntEnum):
class SongIdSelector(Ui_SongIdSelector, QWidget): class SongIdSelector(Ui_SongIdSelector, QWidget):
valueChanged = Signal() valueChanged = Signal()
quickSearchActivated = Signal(Chart)
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@ -126,8 +127,7 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
self.packComboBox.clear() self.packComboBox.clear()
packs = self.db.get_packs() packs = self.db.get_packs()
for pack in packs: for pack in packs:
isAppendPack = re.search(r"_append_.*$", pack.id) if isAppendPack := re.search(r"_append_.*$", pack.id):
if isAppendPack:
basePackId = re.sub(r"_append_.*$", "", pack.id) basePackId = re.sub(r"_append_.*$", "", pack.id)
basePackName = self.db.get_pack(basePackId).name basePackName = self.db.get_pack(basePackId).name
packName = f"{basePackName} - {pack.name}" packName = f"{basePackName} - {pack.name}"
@ -146,8 +146,7 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
def fillSongIdComboBox(self): def fillSongIdComboBox(self):
self.songIdComboBox.clear() self.songIdComboBox.clear()
packId = self.packComboBox.currentData() if packId := self.packComboBox.currentData():
if packId:
if self.mode == SongIdSelectorMode.SongId: if self.mode == SongIdSelectorMode.SongId:
items = self.db.get_songs_by_pack_id(packId) items = self.db.get_songs_by_pack_id(packId)
elif self.mode == SongIdSelectorMode.Chart: elif self.mode == SongIdSelectorMode.Chart:
@ -208,14 +207,15 @@ class SongIdSelector(Ui_SongIdSelector, QWidget):
return False return False
def selectChart(self, chart: Chart): def selectChart(self, chart: Chart):
if not self.selectPack(chart.set): packSelected = self.selectPack(chart.set)
return False songIdSelected = self.selectSongId(chart.song_id)
return self.selectSongId(chart.song_id) return packSelected and songIdSelected
@Slot(QModelIndex) @Slot(QModelIndex)
def searchCompleterSetSelection(self, index: QModelIndex): def searchCompleterSetSelection(self, index: QModelIndex):
chart = index.data(Qt.ItemDataRole.UserRole + 10) # type: Chart chart: Chart = index.data(Qt.ItemDataRole.UserRole + 10)
self.selectChart(chart) self.selectChart(chart)
self.quickSearchActivated.emit(chart)
self.searchLineEdit.clear() self.searchLineEdit.clear()
self.searchLineEdit.clearFocus() self.searchLineEdit.clearFocus()

View File

@ -1,5 +1,4 @@
import logging import logging
import random
from arcaea_offline.calculate import calculate_constants_from_play_rating from arcaea_offline.calculate import calculate_constants_from_play_rating
from arcaea_offline.database import Database from arcaea_offline.database import Database
@ -7,11 +6,17 @@ from arcaea_offline.models import Chart, ScoreBest
from arcaea_offline.utils.rating import rating_class_to_text from arcaea_offline.utils.rating import rating_class_to_text
from arcaea_offline.utils.score import score_to_grade_text from arcaea_offline.utils.score import score_to_grade_text
from PySide6.QtCore import Slot from PySide6.QtCore import Slot
from PySide6.QtWidgets import QLabel, QWidget from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabTools.tabTools_ChartRecommend_ui import ( from ui.designer.tabs.tabTools.tabTools_ChartRecommend_ui import (
Ui_TabTools_ChartRecommend, Ui_TabTools_ChartRecommend,
) )
from ui.extends.tabs.tabTools.tabTools_ChartRecommend import (
ChartsModel,
ChartsWithScoreBestModel,
CustomChartDelegate,
CustomScoreBestDelegate,
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -31,11 +36,25 @@ class TabTools_ChartRecommend(Ui_TabTools_ChartRecommend, QWidget):
self.db = Database() self.db = Database()
self.chartsByConstant = [] self.chartsByConstantModel = ChartsModel(self)
self.chartsRecommendFromPlayRating = [] self.chartsRecommendFromPlayRatingModel = ChartsWithScoreBestModel(self)
self.numLabelFormatString = "{} charts" self.numLabelFormatString = "{} charts"
self.chartDelegate = CustomChartDelegate(self)
self.scoreBestDelegate = CustomScoreBestDelegate(self)
self.chartsByConstant_modelView.setModel(self.chartsByConstantModel)
self.chartsByConstant_modelView.setItemDelegate(self.chartDelegate)
self.chartsRecommendFromPlayRating_modelView.setModel(
self.chartsRecommendFromPlayRatingModel
)
self.chartsRecommendFromPlayRating_modelView.setItemDelegateForColumn(
0, self.chartDelegate
)
self.chartsRecommendFromPlayRating_modelView.setItemDelegateForColumn(
1, self.scoreBestDelegate
)
self.chartsRecommendFromPlayRating_playRatingSpinBox.valueChanged.connect( self.chartsRecommendFromPlayRating_playRatingSpinBox.valueChanged.connect(
self.updateChartsRecommendFromPlayRating self.updateChartsRecommendFromPlayRating
) )
@ -43,81 +62,61 @@ class TabTools_ChartRecommend(Ui_TabTools_ChartRecommend, QWidget):
self.updateChartsRecommendFromPlayRating self.updateChartsRecommendFromPlayRating
) )
self.chartsByConstant_refreshButton.clicked.connect(self.fillChartsByConstant)
self.chartsRecommendFromPlayRating_refreshButton.clicked.connect(
self.fillChartsRecommendFromPlayRating
)
@Slot(float) @Slot(float)
def on_rangeFromPlayRating_playRatingSpinBox_valueChanged(self, value: float): def on_rangeFromPlayRating_playRatingSpinBox_valueChanged(self, value: float):
try: try:
result = calculate_constants_from_play_rating(value) constant = round(
exPlusLower, exPlusUpper = result.EXPlus value, self.rangeFromPlayRating_playRatingSpinBox.decimals()
exLower, exUpper = result.EX
aaLower, aaUpper = result.AA
self.rangeFromPlayRating_ExPlusLabel.setText(
f"{exPlusLower:.3f}~{exPlusUpper:.3f}"
) )
self.rangeFromPlayRating_ExLabel.setText(f"{exLower:.3f}~{exUpper:.3f}") result = calculate_constants_from_play_rating(constant)
self.rangeFromPlayRating_AaLabel.setText(f"{aaLower:.3f}~{aaUpper:.3f}") labels = [
self.rangeFromPlayRating_ExPlusLabel,
self.rangeFromPlayRating_ExLabel,
self.rangeFromPlayRating_AaLabel,
self.rangeFromPlayRating_ALabel,
self.rangeFromPlayRating_BLabel,
self.rangeFromPlayRating_CLabel,
]
for label, constantRange in zip(
labels,
[result.EXPlus, result.EX, result.AA, result.A, result.B, result.C],
):
label.setText(f"{constantRange[0]:.3f}~{constantRange[1]:.3f}")
except Exception: except Exception:
logging.exception("cannot calculate constant from play rating") logging.exception("Cannot calculate constant from play rating:")
self.rangeFromPlayRating_ExPlusLabel.setText("...") self.rangeFromPlayRating_ExPlusLabel.setText("...")
self.rangeFromPlayRating_ExLabel.setText("...") self.rangeFromPlayRating_ExLabel.setText("...")
self.rangeFromPlayRating_AaLabel.setText("...") self.rangeFromPlayRating_AaLabel.setText("...")
def fillChartsByConstant(self):
while item := self.chartsByConstant_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsByConstant, k=min(len(self.chartsByConstant), 6)
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
label = QLabel(self)
label.setText(chartToText(chart))
self.chartsByConstant_gridLayout.addWidget(label, row, i % 3)
@Slot(float) @Slot(float)
def on_chartsByConstant_constantSpinBox_valueChanged(self, value: float): def on_chartsByConstant_constantSpinBox_valueChanged(self, value: float):
self.chartsByConstant = self.db.get_charts_by_constant(int(value * 10)) constant = round(value, self.chartsByConstant_constantSpinBox.decimals())
chartsNum = len(self.chartsByConstant) charts = self.db.get_charts_by_constant(int(constant * 10))
self.chartsByConstant_refreshButton.setEnabled(chartsNum > 6) chartsNum = len(charts)
self.chartsByConstant_numLabel.setText( self.chartsByConstant_numLabel.setText(
self.numLabelFormatString.format(chartsNum) self.numLabelFormatString.format(chartsNum)
) )
self.fillChartsByConstant() self.chartsByConstantModel.setCharts(charts)
def fillChartsRecommendFromPlayRating(self):
while item := self.chartsRecommendFromPlayRating_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsRecommendFromPlayRating,
k=min(len(self.chartsRecommendFromPlayRating), 6),
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
scoreBest = self.db.get_score_best(chart.song_id, chart.rating_class)
label = QLabel(self)
label.setText(f"{chartToText(chart)}<br>-<br>{scoreBestToText(scoreBest)}")
self.chartsRecommendFromPlayRating_gridLayout.addWidget(label, row, i % 3)
def updateChartsRecommendFromPlayRating(self): def updateChartsRecommendFromPlayRating(self):
playRating = self.chartsRecommendFromPlayRating_playRatingSpinBox.value() playRating = self.chartsRecommendFromPlayRating_playRatingSpinBox.value()
bounds = self.chartsRecommendFromPlayRating_boundsSpinBox.value() bounds = self.chartsRecommendFromPlayRating_boundsSpinBox.value()
self.chartsRecommendFromPlayRating = self.db.recommend_charts( charts = self.db.recommend_charts(
playRating, bounds round(
playRating,
self.chartsRecommendFromPlayRating_playRatingSpinBox.decimals(),
),
round(
bounds,
self.chartsRecommendFromPlayRating_boundsSpinBox.decimals(),
),
) )
chartsNum = len(self.chartsRecommendFromPlayRating) chartsNum = len(charts)
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(chartsNum > 6)
self.chartsRecommendFromPlayRating_numLabel.setText( self.chartsRecommendFromPlayRating_numLabel.setText(
self.numLabelFormatString.format(chartsNum) self.numLabelFormatString.format(chartsNum)
) )
self.fillChartsRecommendFromPlayRating() scores = [self.db.get_score_best(c.song_id, c.rating_class) for c in charts]
self.chartsRecommendFromPlayRatingModel.setChartAndScore(charts, scores)
self.chartsRecommendFromPlayRating_modelView.resizeRowsToContents()
self.chartsRecommendFromPlayRating_modelView.resizeColumnsToContents()