Skip to content

Commit

Permalink
refactor sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven committed Nov 18, 2024
1 parent e4b8f07 commit 4491f06
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 135 deletions.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ mypy:
mypy ${MYPY_PKGS}
mypy --check-untyped-defs ${MYPY_STRICT_PKGS}

# mypy has several issues:
# 1. mypy behaves inconsistently between local and CI environments.
# 2. mypy checks other files even if only one file is specified.
#
# So give pyright a try.
PYRIGHT_PKGS=
PYRIGHT_PKGS+=feeluown/gui/uimain/sidebar.py
pyright:
pyright ${PYRIGHT_PKGS}

flake8:
flake8 feeluown/ tests/

Expand Down
24 changes: 13 additions & 11 deletions feeluown/gui/drawers.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,11 +419,11 @@ def draw(self, painter: QPainter, palette: QPalette):


class FireIconDrawer:
def __init__(self, width, padding):
self.width = width
def __init__(self, length, padding):
self.length = length
self.padding = padding

def draw(self, painter):
def paint(self, painter):
# flake8: noqa: E501
# The following path is copied from a SVG file.
path = QPainterPath()
Expand All @@ -450,19 +450,21 @@ def draw(self, painter):
path.closeSubpath()

# Calculate scaling factor
scale_factor = 1024 / (self.width - 2 * self.padding)
scale_factor = 1024 / (self.length - 2 * self.padding)
painter_sf = 1 / scale_factor

# Scale and translate the path
transform = painter.transform()
transform.scale(painter_sf, painter_sf)
transform.translate(self.padding * scale_factor, self.padding * scale_factor)
painter.setTransform(transform)

# Set the brush and pen
pen = painter.pen()
pen.setWidthF(1.5 * scale_factor)
painter.setPen(pen)
with painter_save(painter):
painter.setTransform(transform)

# Set the brush and pen
pen = painter.pen()
pen.setWidthF(1.5 * scale_factor)
painter.setPen(pen)

# Draw the fire shape
painter.drawPath(path)
# Draw the fire shape
painter.drawPath(path)
251 changes: 141 additions & 110 deletions feeluown/gui/uimain/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import QFrame, QLabel, QVBoxLayout, QSizePolicy, QScrollArea, \
QHBoxLayout, QFormLayout, QDialog, QLineEdit, QDialogButtonBox, QMessageBox
QHBoxLayout, QFormLayout, QDialog, QLineEdit, QDialogButtonBox, QMessageBox, \
QWidget

from feeluown.excs import ProviderIOError, NoUserLoggedIn
from feeluown.library import (
Expand All @@ -13,7 +14,7 @@
)
from feeluown.collection import CollectionAlreadyExists, CollectionType
from feeluown.utils import aio
from feeluown.utils.reader import create_reader
from feeluown.utils.reader import create_reader, Reader
from feeluown.utils.aio import run_fn
from feeluown.gui.components import Avatar, CollectionListView
from feeluown.gui.widgets import (
Expand Down Expand Up @@ -107,67 +108,71 @@ async def show_provider_current_user_playlists(self, provider):

playlists = await run_fn(provider.current_user_list_playlists)
reader = await run_fn(provider.current_user_fav_create_playlists_rd)
fav_playlists = create_reader(reader).readall()
reader = create_reader(reader)
assert isinstance(reader, Reader)
fav_playlists = reader.readall()
self._app.pl_uimgr.add(playlists)
self._app.pl_uimgr.add(fav_playlists, is_fav=True)


class _LeftPanel(QFrame):
LVC = ListViewContainer


class ProviderPanel(QWidget):
"""
A panel shows provider-specific contents.
"""
def __init__(self, app: 'GuiApp', parent=None):
super().__init__(parent)
self._app = app

self.home_btn = HomeButton(height=30, parent=self)
self.discovery_btn = DiscoveryButton(height=30, padding=0.2, parent=self)
self.fav_btn = StarButton('我的收藏', height=30, parent=self)
self.fold_top_btn = TriagleButton(length=14, padding=0.2)
self.fold_top_btn.setCheckable(True)
self.collections_header = QLabel('本地收藏集', self)
self.collections_header.setToolTip('我们可以在本地建立『收藏集』来收藏自己喜欢的音乐资源\n\n'
'每个收藏集都以一个独立 .fuo 文件的存在,'
'将鼠标悬浮在收藏集上,可以查看文件所在路径。\n'
'新建 fuo 文件,则可以新建收藏集,文件名即是收藏集的名字。\n\n'
'手动编辑 fuo 文件即可编辑收藏集中的音乐资源,也可以在界面上拖拽来增删歌曲。')

self.playlists_header = QLabel('歌单列表', self)
self.my_music_header = QLabel('我的音乐', self)

self._layout = QVBoxLayout(self)
self.playlists_view = PlaylistsView(self)
self.my_music_view = MyMusicView(self)
self.collections_view = CollectionListView(self._app)

self.collections_con = ListViewContainer(self.collections_header,
self.collections_view)
self.playlists_con = ListViewContainer(self.playlists_header,
self.playlists_view)
self.my_music_con = ListViewContainer(self.my_music_header, self.my_music_view)

self.playlists_view.setModel(self._app.pl_uimgr.model)
self.my_music_view.setModel(self._app.mymusic_uimgr.model)

self._top_separator = Separator(self._app)
self._layout = QVBoxLayout(self)
self._avatar_layout = QHBoxLayout()
self.playlists_con = LVC(self.playlists_header, self.playlists_view)
self.my_music_con = LVC(self.my_music_header, self.my_music_view)

self.playlists_view.show_playlist.connect(
lambda pl: self._app.browser.goto(model=pl))
self.playlists_view.remove_playlist.connect(self._remove_playlist)
self.playlists_con.create_btn.clicked.connect(self._create_playlist)
self._app.current_pvd_ui_mgr.changed.connect(
self.on_current_pvd_ui_changed)
self.discovery_btn.clicked.connect(
lambda: self._app.browser.goto(page='/rec'))
self.fav_btn.clicked.connect(
lambda: self._app.browser.goto(page='/my_fav'))

self.setup_ui()

def setup_ui(self):
self._layout.setSpacing(0)
self._layout.setContentsMargins(16, 10, 16, 0)
self._layout.addWidget(self.home_btn)
self._layout.addWidget(self.collections_con)
self._layout.addWidget(self._top_separator)
self._layout.addLayout(self._avatar_layout)
self._layout.setContentsMargins(0, 0, 0, 0)

self.playlists_view.setFrameShape(QFrame.NoFrame)
self.my_music_view.setFrameShape(QFrame.NoFrame)

self._avatar_layout = QHBoxLayout()
self._avatar_layout.addWidget(Avatar(self._app, height=48))
self._avatar_layout.addWidget(self.fold_top_btn)

self._layout.addLayout(self._avatar_layout)
self._layout.addWidget(self.discovery_btn)
self._layout.addWidget(self.fav_btn)
self._layout.addWidget(self.my_music_con)
self._layout.addWidget(self.playlists_con)
self._layout.addStretch(0)

self.playlists_view.setFrameShape(QFrame.NoFrame)
self.my_music_view.setFrameShape(QFrame.NoFrame)
self.collections_view.setFrameShape(QFrame.NoFrame)
self.setFrameShape(QFrame.NoFrame)
self.collections_con.create_btn.show()
# 让各个音乐库来决定是否显示这些组件
self.playlists_con.hide()
self.my_music_con.hide()
Expand All @@ -176,67 +181,14 @@ def __init__(self, app: 'GuiApp', parent=None):
self.discovery_btn.setToolTip('当前资源提供方未知')
self.fold_top_btn.setToolTip('折叠/打开“主页和本地收藏集”功能')

if self._app.config.ENABLE_NEW_HOMEPAGE is True:
self.home_btn.clicked.connect(
lambda: self._app.browser.goto(page='/homepage'))
else:
self.home_btn.clicked.connect(self.show_library)

self.discovery_btn.clicked.connect(self.show_pool)
self.playlists_view.show_playlist.connect(
lambda pl: self._app.browser.goto(model=pl))
self.collections_view.show_collection.connect(
lambda coll: self._app.browser.goto(page=f'/colls/{coll.identifier}'))
self.collections_view.remove_collection.connect(self._remove_coll)
self.playlists_view.remove_playlist.connect(self._remove_playlist)
self.collections_con.create_btn.clicked.connect(
self.popup_collection_adding_dialog)
self.playlists_con.create_btn.clicked.connect(self._create_playlist)
self._app.current_pvd_ui_mgr.changed.connect(
self.on_current_pvd_ui_changed)
self.discovery_btn.clicked.connect(
lambda: self._app.browser.goto(page='/rec'))
self.fav_btn.clicked.connect(
lambda: self._app.browser.goto(page='/my_fav'))
self.fold_top_btn.clicked.connect(self._toggle_top_layout)

def _toggle_top_layout(self, checked):
widgets = [self._top_separator, self.collections_con, self.home_btn]
if checked:
self.fold_top_btn.set_direction('down')
for w in widgets:
w.hide()
def on_current_pvd_ui_changed(self, pvd_ui, _):
if pvd_ui:
self.discovery_btn.setEnabled(True)
self.fav_btn.setEnabled(True)
self.discovery_btn.setToolTip(f'点击进入 {pvd_ui.provider.name} 推荐页')
else:
self.fold_top_btn.set_direction('up')
for w in widgets:
w.show()

def popup_collection_adding_dialog(self):
dialog = QDialog(self)
# Set WA_DeleteOnClose so that the dialog can be deleted (from self.children).
dialog.setAttribute(Qt.WA_DeleteOnClose)
layout = QFormLayout(dialog)
id_edit = QLineEdit(dialog)
title_edit = QLineEdit(dialog)
layout.addRow('ID', id_edit)
layout.addRow('标题', title_edit)
button_box = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Save)
layout.addRow('', button_box)
button_box.accepted.connect(dialog.accept)
button_box.rejected.connect(dialog.reject)

def create_collection_and_reload():
fname = id_edit.text()
title = title_edit.text()
try:
self._app.coll_mgr.create(fname, title)
except CollectionAlreadyExists:
QMessageBox.warning(self, '警告', f"收藏集 '{fname}' 已存在")
else:
self._app.coll_mgr.refresh()

dialog.accepted.connect(create_collection_and_reload)
dialog.open()
self.discovery_btn.setEnabled(False)
self.fav_btn.setEnabled(False)

def _create_playlist(self):
provider_ui = self._app.current_pvd_ui_mgr.get()
Expand Down Expand Up @@ -282,14 +234,6 @@ async def do():
dialog.accepted.connect(create_playlist_and_reload)
dialog.open()

def show_library(self):
coll_library = self._app.coll_mgr.get_coll_library()
self._app.browser.goto(page=f'/colls/{coll_library.identifier}')

def show_pool(self):
coll = self._app.coll_mgr.get(CollectionType.sys_pool)
self._app.browser.goto(page=f'/colls/{coll.identifier}')

def _remove_playlist(self, playlist):

async def do():
Expand All @@ -307,6 +251,102 @@ async def do():
box.accepted.connect(lambda: aio.run_afn(do))
box.open()


class _LeftPanel(QFrame):

def __init__(self, app: 'GuiApp', parent=None):
super().__init__(parent)
self._app = app

self.home_btn = HomeButton(height=30, parent=self)
self.collections_header = QLabel('本地收藏集', self)
self.collections_header.setToolTip('我们可以在本地建立『收藏集』来收藏自己喜欢的音乐资源\n\n'
'每个收藏集都以一个独立 .fuo 文件的存在,'
'将鼠标悬浮在收藏集上,可以查看文件所在路径。\n'
'新建 fuo 文件,则可以新建收藏集,文件名即是收藏集的名字。\n\n'
'手动编辑 fuo 文件即可编辑收藏集中的音乐资源,也可以在界面上拖拽来增删歌曲。')
self.collections_view = CollectionListView(self._app)
self.collections_con = ListViewContainer(self.collections_header,
self.collections_view)
self._top_separator = Separator(self._app)
self.provider_bar = ProviderPanel(self._app)

# For backward compatibility.
self.playlists_con = self.provider_bar.playlists_con
self.my_music_con = self.provider_bar.my_music_con
self.playlists_header = self.provider_bar.playlists_header

self._layout = QVBoxLayout(self)

self._layout.setSpacing(0)
self._layout.setContentsMargins(16, 10, 16, 0)
self._layout.addWidget(self.home_btn)
self._layout.addWidget(self.collections_con)
self._layout.addWidget(self._top_separator)
self._layout.addWidget(self.provider_bar)
self._layout.addStretch(0)

self.collections_view.show_collection.connect(
lambda coll: self._app.browser.goto(page=f'/colls/{coll.identifier}'))
self.collections_view.remove_collection.connect(self._remove_coll)
self.collections_con.create_btn.clicked.connect(
self.popup_collection_adding_dialog)
self.collections_view.setFrameShape(QFrame.NoFrame)
self.setFrameShape(QFrame.NoFrame)
self.collections_con.create_btn.show()
self.provider_bar.fold_top_btn.clicked.connect(self._toggle_top_layout)
if self._app.config.ENABLE_NEW_HOMEPAGE is True:
self.home_btn.clicked.connect(
lambda: self._app.browser.goto(page='/homepage'))
else:
self.home_btn.clicked.connect(self.show_library)

def _toggle_top_layout(self, checked):
widgets = [self._top_separator, self.collections_con, self.home_btn]
if checked:
self.provider_bar.fold_top_btn.set_direction('down')
for w in widgets:
w.hide()
else:
self.provider_bar.fold_top_btn.set_direction('up')
for w in widgets:
w.show()

def popup_collection_adding_dialog(self):
dialog = QDialog(self)
# Set WA_DeleteOnClose so that the dialog can be deleted (from self.children).
dialog.setAttribute(Qt.WA_DeleteOnClose)
layout = QFormLayout(dialog)
id_edit = QLineEdit(dialog)
title_edit = QLineEdit(dialog)
layout.addRow('ID', id_edit)
layout.addRow('标题', title_edit)
button_box = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Save)
layout.addRow('', button_box)
button_box.accepted.connect(dialog.accept)
button_box.rejected.connect(dialog.reject)

def create_collection_and_reload():
fname = id_edit.text()
title = title_edit.text()
try:
self._app.coll_mgr.create(fname, title)
except CollectionAlreadyExists:
QMessageBox.warning(self, '警告', f"收藏集 '{fname}' 已存在")
else:
self._app.coll_mgr.refresh()

dialog.accepted.connect(create_collection_and_reload)
dialog.open()

def show_library(self):
coll_library = self._app.coll_mgr.get_coll_library()
self._app.browser.goto(page=f'/colls/{coll_library.identifier}')

def show_pool(self):
coll = self._app.coll_mgr.get(CollectionType.sys_pool)
self._app.browser.goto(page=f'/colls/{coll.identifier}')

def _remove_coll(self, coll):

def do():
Expand All @@ -317,12 +357,3 @@ def do():
QMessageBox.Yes | QMessageBox.No, self)
box.accepted.connect(do)
box.open()

def on_current_pvd_ui_changed(self, pvd_ui, _):
if pvd_ui:
self.discovery_btn.setEnabled(True)
self.fav_btn.setEnabled(True)
self.discovery_btn.setToolTip(f'点击进入 {pvd_ui.provider.name} 推荐页')
else:
self.discovery_btn.setEnabled(False)
self.fav_btn.setEnabled(False)
2 changes: 1 addition & 1 deletion feeluown/gui/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
PlusButton, TriagleButton, DiscoveryButton,
SelfPaintAbstractIconTextButton, CalendarButton, RankButton,
StarButton, PlayPauseButton, PlayNextButton, PlayPreviousButton,
MVButton, VolumeButton,
MVButton, VolumeButton, HotButton,
)
Loading

0 comments on commit 4491f06

Please sign in to comment.