From 2c04c298e38bfa4f3444a6e659200f0829ff5f42 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 17 Jun 2021 14:16:23 -0700 Subject: [PATCH] Update the GUI a bit more, make things look nicer --- playtypus/__init__.py | 10 ++- playtypus/mainwindow.py | 22 +++--- playtypus/threads.py | 9 ++- playtypus/ui_mainwindow.py | 136 +++++++++++++++---------------------- 4 files changed, 84 insertions(+), 93 deletions(-) diff --git a/playtypus/__init__.py b/playtypus/__init__.py index 09b64eb..2a6ae97 100644 --- a/playtypus/__init__.py +++ b/playtypus/__init__.py @@ -1,10 +1,18 @@ -from PyQt5 import QtWidgets +import qtawesome as qta +from PyQt5 import QtGui, QtWidgets from playtypus.mainwindow import MainWindow def main(): """Main""" app = QtWidgets.QApplication([]) + # Set up icon colours + palette = app.palette() + qta.set_defaults(color=palette.color(QtGui.QPalette.Active, + QtGui.QPalette.WindowText), + color_disabled=palette.color(QtGui.QPalette.Disabled, + QtGui.QPalette.WindowText)) + # Create the main window and run the app main_window = MainWindow() main_window.show() return app.exec() diff --git a/playtypus/mainwindow.py b/playtypus/mainwindow.py index 51e7f32..e01dd60 100644 --- a/playtypus/mainwindow.py +++ b/playtypus/mainwindow.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from funksnake import Funkwhale -from PyQt5 import QtCore, QtWidgets, QtNetwork +from PyQt5 import QtCore, QtWidgets from playtypus.ui_mainwindow import UiMainWindow from playtypus.settingsdialog import SettingsDialog @@ -12,17 +12,19 @@ class MainWindow(QtWidgets.QMainWindow, UiMainWindow): super().__init__(parent) self.setup_ui() self.settingsAction.triggered.connect(self.on_settings_action_triggered) - self.settings = QtCore.QSettings('info.snyman.pyfunkwhale', 'PyFunkwhale') - self.network_manager = QtNetwork.QNetworkAccessManager() + self.settings = QtCore.QSettings('info.snyman.playtypus', 'Playtypus') self.settings_dialog = SettingsDialog(self) self.funkwhale = None self.threads = {} + # Check for Funkwhale settings, and load all the things if self.settings.contains('funkwhale/server_url'): self.setup_funkwhale(self.settings.value('funkwhale/server_url'), self.settings.value('funkwhale/username', None), self.settings.value('funkwhale/password', None)) - self.load_albums() - # self.load_artists() + + @property + def is_funkwhale_active(self): + return self.funkwhale and self.funkwhale.token def run_thread(self, worker, thread_name): """ @@ -98,16 +100,19 @@ class MainWindow(QtWidgets.QMainWindow, UiMainWindow): self.funkwhale = Funkwhale(server_url) if username and password: self.funkwhale.login(username, password) + if self.is_funkwhale_active: + self.load_albums() + # self.load_artists() def load_albums(self): - if not self.funkwhale or not self.funkwhale.token: + if not self.is_funkwhale_active: return worker = AlbumWorker() worker.window = self self.run_thread(worker, 'get-albums') def load_artists(self): - if not self.funkwhale or not self.funkwhale.token: + if not self.is_funkwhale_active: return self.artistListWidget.clear() for artist in self.funkwhale.artists.list()['results']: @@ -117,7 +122,8 @@ class MainWindow(QtWidgets.QMainWindow, UiMainWindow): self.settings_dialog.server_url = self.settings.value('funkwhale/server_url', '') self.settings_dialog.username = self.settings.value('funkwhale/username', '') self.settings_dialog.password = self.settings.value('funkwhale/password', '') - if self.settings_dialog.exec() == QtWidgets.QDialog.Accepted: + if self.settings_dialog.exec() == QtWidgets.QDialog.Accepted \ + and self.settings.value('funkwhale/server_url', '') != self.settings_dialog.server_url: self.settings.setValue('funkwhale/server_url', self.settings_dialog.server_url) self.settings.setValue('funkwhale/username', self.settings_dialog.username) self.settings.setValue('funkwhale/password', self.settings_dialog.password) diff --git a/playtypus/threads.py b/playtypus/threads.py index b3dd0ac..cd2468d 100644 --- a/playtypus/threads.py +++ b/playtypus/threads.py @@ -49,6 +49,7 @@ class AlbumWorker(ThreadWorker): """ A thread worker to fetch the album art """ + ALBUM_TEMPLATE = "{title}\n{artist}\n{year}" window = None def start(self): @@ -58,10 +59,16 @@ class AlbumWorker(ThreadWorker): return self.window.albumListWidget.clear() for album in self.window.funkwhale.albums.list()['results']: - album_item = QtWidgets.QListWidgetItem(album['title']) + details = { + 'title': album['title'], + 'year': album['release_date'][:4] if album.get('release_date') else '', + 'artist': album['artist']['name'] + } + album_item = QtWidgets.QListWidgetItem(self.ALBUM_TEMPLATE.format(**details)) self.window.albumListWidget.addItem(album_item) artwork_worker = AlbumArtWorker() artwork_worker.album_item = album_item artwork_worker.artwork_url = album['cover']['urls']['medium_square_crop'] self.window.run_thread(artwork_worker, 'album-{}'.format(album['title'])) + self.window.update_album_total(self.window.albumListWidget.count()) self.quit.emit() diff --git a/playtypus/ui_mainwindow.py b/playtypus/ui_mainwindow.py index d27e479..e3b17cd 100644 --- a/playtypus/ui_mainwindow.py +++ b/playtypus/ui_mainwindow.py @@ -20,73 +20,39 @@ class UiMainWindow(object): self.centralLayout.setContentsMargins(0, 0, 0, 0) self.centralLayout.setSpacing(0) self.centralLayout.setObjectName("centralLayout") - self.playbackWidget = QtWidgets.QWidget(self.centralwidget) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.playbackWidget.sizePolicy().hasHeightForWidth()) - self.playbackWidget.setSizePolicy(sizePolicy) - self.playbackWidget.setMinimumSize(QtCore.QSize(0, 36)) - self.playbackWidget.setObjectName("playbackWidget") - self.playbackLayout = QtWidgets.QHBoxLayout(self.playbackWidget) - self.playbackLayout.setContentsMargins(0, 0, 0, 0) - self.playbackLayout.setSpacing(0) - self.playbackLayout.setObjectName("playbackLayout") - self.toggleButton = QtWidgets.QToolButton(self.playbackWidget) - self.toggleButton.setIcon(qta.icon("mdi.chevron-down")) - self.toggleButton.setAutoRaise(True) - self.toggleButton.setObjectName("toggleButton") - self.playbackLayout.addWidget(self.toggleButton) - self.previousButton = QtWidgets.QToolButton(self.playbackWidget) - self.previousButton.setIcon(qta.icon("mdi.skip-previous")) - self.previousButton.setAutoRaise(True) - self.previousButton.setObjectName("previousButton") - self.playbackLayout.addWidget(self.previousButton) - self.playButton = QtWidgets.QToolButton(self.playbackWidget) - self.playButton.setIcon(qta.icon("mdi.play")) - self.playButton.setAutoRaise(True) - self.playButton.setObjectName("playButton") - self.playbackLayout.addWidget(self.playButton) - self.nextButton = QtWidgets.QToolButton(self.playbackWidget) - self.nextButton.setIcon(qta.icon("mdi.skip-next")) - self.nextButton.setAutoRaise(True) - self.nextButton.setObjectName("nextButton") - self.playbackLayout.addWidget(self.nextButton) - self.positionLabel = QtWidgets.QLabel(self.playbackWidget) + # Playback toolbar + self.playbackToolBar = QtWidgets.QToolBar(self) + self.playbackToolBar.setMovable(False) + self.playbackToolBar.setIconSize(QtCore.QSize(32, 32)) + self.playbackToolBar.setObjectName("playbackToolBar") + self.toggleAction = self.playbackToolBar.addAction(qta.icon("mdi.chevron-down"), '') + self.previousAction = self.playbackToolBar.addAction(qta.icon("mdi.skip-previous"), '') + self.playAction = self.playbackToolBar.addAction(qta.icon("mdi.play"), '') + self.nextAction = self.playbackToolBar.addAction(qta.icon("mdi.skip-next"), '') + self.positionLabel = QtWidgets.QLabel() self.positionLabel.setAlignment(QtCore.Qt.AlignCenter) self.positionLabel.setObjectName("positionLabel") - self.playbackLayout.addWidget(self.positionLabel) - self.positionSlider = QtWidgets.QSlider(self.playbackWidget) + self.playbackToolBar.addWidget(self.positionLabel) + self.positionSlider = QtWidgets.QSlider() self.positionSlider.setOrientation(QtCore.Qt.Horizontal) self.positionSlider.setObjectName("positionSlider") - self.playbackLayout.addWidget(self.positionSlider) - self.shuffleButton = QtWidgets.QToolButton(self.playbackWidget) - self.shuffleButton.setIcon(qta.icon("mdi.shuffle")) - self.shuffleButton.setAutoRaise(True) - self.shuffleButton.setObjectName("shuffleButton") - self.playbackLayout.addWidget(self.shuffleButton) - self.repeatButton = QtWidgets.QToolButton(self.playbackWidget) - self.repeatButton.setIcon(qta.icon("mdi.repeat")) - self.repeatButton.setAutoRaise(True) - self.repeatButton.setObjectName("repeatButton") - self.playbackLayout.addWidget(self.repeatButton) - self.muteButton = QtWidgets.QToolButton(self.playbackWidget) - self.muteButton.setIcon(qta.icon("mdi.volume-high")) - self.muteButton.setCheckable(True) - self.muteButton.setAutoRaise(True) - self.muteButton.setObjectName("muteButton") - self.playbackLayout.addWidget(self.muteButton) - self.volumeSlider = QtWidgets.QSlider(self.playbackWidget) + self.playbackToolBar.addWidget(self.positionSlider) + self.shuffleAction = self.playbackToolBar.addAction(qta.icon("mdi.shuffle"), '') + self.repeatAction = self.playbackToolBar.addAction(qta.icon("mdi.repeat"), '') + self.muteAction = self.playbackToolBar.addAction(qta.icon("mdi.volume-high"), '') + self.muteAction.setCheckable(True) + self.volumeSlider = QtWidgets.QSlider() self.volumeSlider.setOrientation(QtCore.Qt.Horizontal) self.volumeSlider.setObjectName("volumeSlider") - self.playbackLayout.addWidget(self.volumeSlider) - self.menuButton = QtWidgets.QToolButton(self.playbackWidget) - self.menuButton.setIcon(qta.icon("mdi.menu")) - self.menuButton.setPopupMode(QtWidgets.QToolButton.DelayedPopup) - self.menuButton.setAutoRaise(True) - self.menuButton.setObjectName("menuButton") - self.playbackLayout.addWidget(self.menuButton) - self.centralLayout.addWidget(self.playbackWidget) + self.playbackToolBar.addWidget(self.volumeSlider) + self.mainMenu = QtWidgets.QMenu() + self.settingsAction = self.mainMenu.addAction(qta.icon('mdi.application-settings'), '') + self.menuAction = self.playbackToolBar.addAction(qta.icon("mdi.menu"), '') + self.menuAction.setMenu(self.mainMenu) + menuButton = self.playbackToolBar.widgetForAction(self.menuAction) + self.menuAction.triggered.connect(menuButton.showMenu) + self.addToolBar(self.playbackToolBar) + # Splitter and main components self.splitter = QtWidgets.QSplitter(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) @@ -97,6 +63,7 @@ class UiMainWindow(object): self.splitter.setHandleWidth(1) self.splitter.setObjectName("splitter") self.viewListWidget = QtWidgets.QListWidget(self.splitter) + self.viewListWidget.setIconSize(QtCore.QSize(40, 40)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -116,19 +83,21 @@ class UiMainWindow(object): self.albumPageTitleLayout.setSpacing(0) self.albumPageTitleLayout.setObjectName("albumPageTitleLayout") self.albumPageIconLabel = QtWidgets.QLabel(self.albumPage) - self.albumPageIconLabel.setPixmap( - qta.icon('mdi.album').pixmap(self.albumPageIconLabel.geometry().height())) + self.albumPageIconLabel.setMaximumSize(36, 36) + self.albumPageIconLabel.setPixmap(qta.icon('mdi.album').pixmap(32)) self.albumPageTitleLayout.addWidget(self.albumPageIconLabel) self.albumPageTitleLabel = QtWidgets.QLabel(self.albumPage) self.albumPageTitleLayout.addWidget(self.albumPageTitleLabel) + self.albumPageTotalLabel = QtWidgets.QLabel(self.albumPage) + self.albumPageTotalLabel.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight) + self.albumPageTotalLabel.setIndent(4) + self.albumPageTotalLabel.setText('0') + self.albumPageTitleLayout.addWidget(self.albumPageTotalLabel) self.albumPageLayout.addLayout(self.albumPageTitleLayout) self.albumListWidget = QtWidgets.QListWidget(self.albumPage) self.albumListWidget.setObjectName("albumListWidget") self.albumListWidget.setSortingEnabled(True) - # self.albumListWidget.setViewMode(QtWidgets.QListView.IconMode) - # self.albumListWidget.setMovement(QtWidgets.QListView.Static) self.albumListWidget.setIconSize(QtCore.QSize(100, 100)) - # self.albumListWidget.setGridSize(QtCore.QSize(128, 128)) self.albumPageLayout.addWidget(self.albumListWidget) self.stackedWidget.addWidget(self.albumPage) self.artistPage = QtWidgets.QWidget() @@ -137,6 +106,17 @@ class UiMainWindow(object): self.artistPageLayout.setContentsMargins(0, 0, 0, 0) self.artistPageLayout.setSpacing(0) self.artistPageLayout.setObjectName("artistPageLayout") + self.artistPageTitleLayout = QtWidgets.QHBoxLayout() + self.artistPageTitleLayout.setContentsMargins(0, 0, 0, 0) + self.artistPageTitleLayout.setSpacing(0) + self.artistPageTitleLayout.setObjectName("artistPageTitleLayout") + self.artistPageIconLabel = QtWidgets.QLabel(self.artistPage) + self.artistPageIconLabel.setMaximumSize(36, 36) + self.artistPageIconLabel.setPixmap(qta.icon('mdi.account').pixmap(32)) + self.artistPageTitleLayout.addWidget(self.artistPageIconLabel) + self.artistPageTitleLabel = QtWidgets.QLabel(self.artistPage) + self.artistPageTitleLayout.addWidget(self.artistPageTitleLabel) + self.artistPageLayout.addLayout(self.artistPageTitleLayout) self.artistListWidget = QtWidgets.QListWidget(self.artistPage) self.artistListWidget.setObjectName("artistListWidget") self.artistListWidget.setSortingEnabled(True) @@ -169,11 +149,6 @@ class UiMainWindow(object): self.statusbar = QtWidgets.QStatusBar(self) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) - self.actionPlay = QtWidgets.QAction(self) - self.actionPlay.setObjectName("actionPlay") - - self.mainMenu = QtWidgets.QMenu(self) - self.settingsAction = self.mainMenu.addAction(qta.icon('mdi.application-settings'), '') self.albumsListItem = QtWidgets.QListWidgetItem(qta.icon('mdi.album'), '') self.artistsListItem = QtWidgets.QListWidgetItem(qta.icon('mdi.account'), '') @@ -183,7 +158,6 @@ class UiMainWindow(object): self.splitter.setStretchFactor(1, 1) self.retranslate_ui() - self.menuButton.clicked.connect(self.on_menu_button_clicked) self.viewListWidget.currentRowChanged.connect(self.on_view_list_current_row_changed) self.viewListWidget.setCurrentRow(0) QtCore.QMetaObject.connectSlotsByName(self) @@ -192,21 +166,14 @@ class UiMainWindow(object): def retranslate_ui(self): _translate = QtCore.QCoreApplication.translate - self.setWindowTitle(_translate("MainWindow", "PyFunkwhale")) - self.toggleButton.setText(_translate("MainWindow", "...")) - self.previousButton.setText(_translate("MainWindow", "...")) - self.playButton.setText(_translate("MainWindow", "...")) - self.nextButton.setText(_translate("MainWindow", "...")) + self.setWindowTitle(_translate("MainWindow", "Playtypus")) self.positionLabel.setText(_translate("MainWindow", "01:43")) - self.shuffleButton.setText(_translate("MainWindow", "...")) - self.repeatButton.setText(_translate("MainWindow", "...")) - self.muteButton.setText(_translate("MainWindow", "...")) - self.menuButton.setText(_translate("MainWindow", "...")) - self.actionPlay.setText(_translate("MainWindow", "&Play")) - self.actionPlay.setToolTip(_translate("MainWindow", "Play")) + self.playAction.setText(_translate("MainWindow", "&Play")) + self.playAction.setToolTip(_translate("MainWindow", "Play")) self.settingsAction.setText(_translate("MainWindow", "&Configure")) self.albumsListItem.setText(_translate("MainWindow", "Albums")) self.albumPageTitleLabel.setText(_translate("MainWindow", "Albums")) + self.artistPageTitleLabel.setText(_translate("MainWindow", "Artists")) self.artistsListItem.setText(_translate("MainWindow", "Artists")) self.tracksListItem.setText(_translate("MainWindow", "Tracks")) @@ -217,3 +184,6 @@ class UiMainWindow(object): def on_view_list_current_row_changed(self, current_row): self.stackedWidget.setCurrentIndex(current_row) + + def update_album_total(self, value): + self.albumPageTotalLabel.setText(str(value))