Skip to content
This repository has been archived by the owner on May 3, 2019. It is now read-only.

Commit

Permalink
Move Hotkeys to presentation layer
Browse files Browse the repository at this point in the history
See #161
  • Loading branch information
ColinDuquesnoy committed Dec 3, 2017
1 parent b05e7f9 commit 7bfc28b
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 27 deletions.
8 changes: 4 additions & 4 deletions docs/developers/PlantUml/Application.puml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace MellowPlayer.Infrastructure {

IApplication <|.. ApplicationDecorator

class SingleInstance {
class SingleInstance #PaleGreen {
+ initialize()
+ run()
}
Expand Down Expand Up @@ -177,13 +177,13 @@ namespace MellowPlayer.Presentation {
' - [x] MainWindow
' - [x] IQmlApplicationEngine
' - [x] QmlApplicationEngine
' - [ ] SingleInstance
' - [x] SingleInstance
'
'- [ ] bind IContextProperties and use them in all existing context properties, remove registration in MainWindowViewModel
'
'- [ ] Copy some classes from infrastructure to presentation (and rename old one with a Deprecated prefix) and make them use IMainWindow instead of IDeprecatedMainWindow
' - [ ] Hotkeys
' - [ ] Mpris
'
'- [ ] bind IContextProperties and use them in all existing context properties, remove registration in MainWindowViewModel
'- [ ] bind IApplication to a fully decorated instance
'- [ ] Create Program class and use it in main
'- [ ] Delete all deprecated classes, the application should now work as before but with a brand new internal design :-)
Expand Down
18 changes: 18 additions & 0 deletions lib/MellowPlayer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# build QxtGlobalShortcut lib
if (NOT qxtglobalshortcut_FOUND)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/qxtglobalshortcut.cpp)
if (WIN32)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/win/qxtglobalshortcut_win.cpp)
elseif(APPLE)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/mac/qxtglobalshortcut_mac.cpp)
elseif(UNIX)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/x11/qxtglobalshortcut_x11.cpp)
endif()
add_definitions(-DBUILD_QXT_CORE -DBUILD_QXT_GUI -DQXT_STATIC)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/core)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/)
include_directories(SYSTEM ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
add_library(qxtglobalshortcut STATIC ${SOURCE_FILES})
target_link_libraries(qxtglobalshortcut Qt5::Core Qt5::Widgets)
endif()

add_subdirectory(Domain)
add_subdirectory(Infrastructure)
add_subdirectory(Presentation)
17 changes: 1 addition & 16 deletions lib/MellowPlayer/Infrastructure/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,34 @@ file(GLOB_RECURSE PLATFORM_FILTERS_HEADERS Platform/Filters/*.hpp)
set(SOURCE_FILES ${SOURCE_FILES} ${PLATFORM_FILTERS_SOURCES})
set(HEADER_FILES ${HEADER_FILES} ${PLATFORM_FILTERS_HEADERS})


if (NOT qxtglobalshortcut_FOUND)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/qxtglobalshortcut.cpp)
endif()

if (WIN32)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/win/qxtglobalshortcut_win.cpp)
file(GLOB_RECURSE PLATFORM_SOURCE_FILES Platform/Windows/*.cpp)
file(GLOB_RECURSE PLATFORM_HEADER_FILES Platform/Windows/*.hpp)
set(SOURCE_FILES ${SOURCE_FILES} ${PLATFORM_SOURCE_FILES})
set(HEADER_FILES ${HEADER_FILES} ${PLATFORM_HEADER_FILES})
elseif(APPLE)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/mac/qxtglobalshortcut_mac.cpp)
file(GLOB_RECURSE PLATFORM_SOURCE_FILES Platform/OSX/*.cpp)
file(GLOB_RECURSE PLATFORM_HEADER_FILES Platform/OSX/*.hpp)
set(SOURCE_FILES ${SOURCE_FILES} ${PLATFORM_SOURCE_FILES})
set(HEADER_FILES ${HEADER_FILES} ${PLATFORM_HEADER_FILES})
elseif(UNIX)
file(GLOB_RECURSE PLATFORM_SOURCE_FILES Platform/Linux/*.cpp)
file(GLOB_RECURSE PLATFORM_HEADER_FILES Platform/Linux/*.hpp)
if (NOT qxtglobalshortcut_FOUND)
set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/x11/qxtglobalshortcut_x11.cpp)
endif()
set(SOURCE_FILES ${SOURCE_FILES} ${PLATFORM_SOURCE_FILES})
set(HEADER_FILES ${HEADER_FILES} ${PLATFORM_HEADER_FILES})
endif()

add_definitions(-DBUILD_QXT_CORE -DBUILD_QXT_GUI -DQXT_STATIC)
if (NOT qxtglobalshortcut_FOUND)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/core)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/libqxt/src/widgets/)
endif()
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rdparty/spdlog-0.11.0/include/)
include_directories(SYSTEM ${Qt5Gui_PRIVATE_INCLUDE_DIRS})

add_library(${LIB_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(${LIB_NAME} ${PROJECT_NAME}.Domain
Qt5::Concurrent Qt5::Core Qt5::Widgets Qt5::Network Qt5::Sql)
Qt5::Concurrent Qt5::Core Qt5::Widgets Qt5::Network Qt5::Sql qxtglobalshortcut)
if(UNIX AND NOT APPLE)
target_link_libraries(${LIB_NAME} Qt5::DBus)
if (qxtglobalshortcut_FOUND)
target_link_libraries(${LIB_NAME} qxtglobalshortcut)
endif()
endif()
if (USE_PRECOMPILED_HEADER)
set_target_properties(${LIB_NAME} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "stdafx.hpp")
Expand Down
6 changes: 5 additions & 1 deletion lib/MellowPlayer/Presentation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set(LIB_NAME "${PROJECT_NAME}.Presentation")

glob_recurse_excl(HEADER_FILES *.hpp "Presenters")
glob_recurse_excl(SOURCE_FILES *.cpp "Presenters")

file(GLOB_RECURSE QML_FILES Views/*.qml)
file(GLOB_RECURSE QRC_FILES *.qrc)
file(GLOB_RECURSE CONF_FILES *.conf)
Expand All @@ -27,7 +28,10 @@ SET(CMAKE_DEBUG_POSTFIX "")
add_library(${LIB_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES} ${QRC_FILES} ${QML_FILES} ${CONF_FILES})
target_link_libraries(${LIB_NAME} ${PROJECT_NAME}.Domain
Qt5::Core Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::Svg
Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets)
Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets qxtglobalshortcut)
if(UNIX AND NOT APPLE)
target_link_libraries(${LIB_NAME} Qt5::DBus)
endif()
if (USE_PRECOMPILED_HEADER)
set_target_properties(${LIB_NAME} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "stdafx.hpp")
set_target_properties(${LIB_NAME} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
Expand Down
124 changes: 124 additions & 0 deletions lib/MellowPlayer/Presentation/Hotkeys/Hotkeys.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include "Hotkeys.hpp"
#include <MellowPlayer/Domain/Logging/ILogger.hpp>
#include <MellowPlayer/Domain/Logging/LoggingManager.hpp>
#include <MellowPlayer/Domain/Logging/LoggingMacros.hpp>
#include <MellowPlayer/Domain/Player/IPlayer.hpp>
#include <MellowPlayer/Domain/Settings/Setting.hpp>
#include <MellowPlayer/Domain/Settings/Settings.hpp>
#include <MellowPlayer/Presentation/MainWindow.hpp>
#include <qxtglobalshortcut.h>

using namespace MellowPlayer::Domain;
using namespace MellowPlayer::Presentation;

Hotkeys::Hotkeys(IPlayer& player, Settings& settings, IMainWindow& mainWindow)
: QObject(nullptr),
logger_(LoggingManager::logger("Hotkeys")),
player_(player),
mainWindow_(mainWindow),
playShortcutSetting_(settings.get(SettingKey::SHORTCUTS_PLAY)),
nextShortcutSetting_(settings.get(SettingKey::SHORTCUTS_NEXT)),
previousShortcutSetting_(settings.get(SettingKey::SHORTCUTS_PREVIOUS)),
favoriteShortcutSetting_(settings.get(SettingKey::SHORTCUTS_FAVORITE)),
restoreWindowShortcutSetting_(settings.get(SettingKey::SHORTCUTS_RESTORE_WINDOW))
{
connect(&playShortcutSetting_, &Setting::valueChanged, this, &Hotkeys::updatePlayShortcut);
connect(&nextShortcutSetting_, &Setting::valueChanged, this, &Hotkeys::updateNextShortcut);
connect(&previousShortcutSetting_, &Setting::valueChanged, this, &Hotkeys::updatePreviousShorcut);
connect(&favoriteShortcutSetting_, &Setting::valueChanged, this, &Hotkeys::updateFavoriteShortcut);
connect(&restoreWindowShortcutSetting_, &Setting::valueChanged, this, &Hotkeys::updateRestoreWindowShortcut);
}

void Hotkeys::togglePlayPause()
{
player_.togglePlayPause();
}

void Hotkeys::next()
{
player_.next();
}

void Hotkeys::previous()
{
player_.previous();
}

void Hotkeys::toggleFavoriteSong()
{
player_.toggleFavoriteSong();
}

Hotkeys::~Hotkeys()
{
}

void Hotkeys::start()
{

playShortcut_ = new QxtGlobalShortcut(this);
updatePlayShortcut();
connect(playShortcut_, &QxtGlobalShortcut::activated, this, &Hotkeys::togglePlayPause);

nextShortcut_ = new QxtGlobalShortcut(this);
updateNextShortcut();
connect(nextShortcut_, &QxtGlobalShortcut::activated, this, &Hotkeys::next);

previousShortcut_ = new QxtGlobalShortcut(this);
updatePreviousShorcut();
connect(previousShortcut_, &QxtGlobalShortcut::activated, this, &Hotkeys::previous);

favoriteShortcut_ = new QxtGlobalShortcut(this);
updateFavoriteShortcut();
connect(favoriteShortcut_, &QxtGlobalShortcut::activated, this, &Hotkeys::toggleFavoriteSong);

restoreWindowShortcut_ = new QxtGlobalShortcut(this);
updateRestoreWindowShortcut();
connect(restoreWindowShortcut_, &QxtGlobalShortcut::activated, this, &Hotkeys::restoreWindow);

#ifdef Q_OS_WIN
auto mediaShortcut = new QxtGlobalShortcut(this);
mediaShortcut->setShortcut(QKeySequence(Qt::Key_MediaPlay));
connect(mediaShortcut, &QxtGlobalShortcut::activated, this, &Hotkeys::togglePlayPause);

mediaShortcut = new QxtGlobalShortcut(this);
mediaShortcut->setShortcut(QKeySequence(Qt::Key_MediaNext));
connect(mediaShortcut, &QxtGlobalShortcut::activated, this, &Hotkeys::next);

mediaShortcut = new QxtGlobalShortcut(this);
mediaShortcut->setShortcut(QKeySequence(Qt::Key_MediaPrevious));
connect(mediaShortcut, &QxtGlobalShortcut::activated, this, &Hotkeys::previous);
#endif

LOG_DEBUG(logger_, "service started");
}

void Hotkeys::updatePlayShortcut() const
{
playShortcut_->setShortcut(QKeySequence(playShortcutSetting_.value().toString()));
}

void Hotkeys::updateNextShortcut() const
{
nextShortcut_->setShortcut(QKeySequence(nextShortcutSetting_.value().toString()));
}

void Hotkeys::updatePreviousShorcut() const
{
previousShortcut_->setShortcut(QKeySequence(previousShortcutSetting_.value().toString()));
}

void Hotkeys::updateFavoriteShortcut() const
{
favoriteShortcut_->setShortcut(QKeySequence(favoriteShortcutSetting_.value().toString()));
}

void Hotkeys::restoreWindow()
{
mainWindow_.show();
}

void Hotkeys::updateRestoreWindowShortcut() const
{
restoreWindowShortcut_->setShortcut(QKeySequence(restoreWindowShortcutSetting_.value().toString()));
}
60 changes: 60 additions & 0 deletions lib/MellowPlayer/Presentation/Hotkeys/Hotkeys.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include <MellowPlayer/Presentation/Hotkeys/IHotkeys.hpp>
#include <QObject>

class QxtGlobalShortcut;

namespace MellowPlayer::Domain
{
class IPlayer;
class ILogger;
class Setting;
class Settings;
class IDeprecatedMainWindow;
}

namespace MellowPlayer::Presentation
{
class IMainWindow;

class Hotkeys : public QObject, public IHotkeys
{
Q_OBJECT
public:
Hotkeys(Domain::IPlayer& player, Domain::Settings& settings, IMainWindow& mainWindow);
~Hotkeys();

void start() override;

public slots:
void togglePlayPause() override;
void next() override;
void previous() override;
void toggleFavoriteSong() override;
void restoreWindow() override;

private:
void updateFavoriteShortcut() const;
void updatePreviousShorcut() const;
void updateNextShortcut() const;
void updatePlayShortcut() const;
void updateRestoreWindowShortcut() const;

Domain::ILogger& logger_;
Domain::IPlayer& player_;
IMainWindow& mainWindow_;

QxtGlobalShortcut* playShortcut_;
QxtGlobalShortcut* nextShortcut_;
QxtGlobalShortcut* previousShortcut_;
QxtGlobalShortcut* favoriteShortcut_;
QxtGlobalShortcut* restoreWindowShortcut_;

Domain::Setting& playShortcutSetting_;
Domain::Setting& nextShortcutSetting_;
Domain::Setting& previousShortcutSetting_;
Domain::Setting& favoriteShortcutSetting_;
Domain::Setting& restoreWindowShortcutSetting_;
};
}
17 changes: 17 additions & 0 deletions lib/MellowPlayer/Presentation/Hotkeys/IHotkeys.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

namespace MellowPlayer::Presentation
{
class IHotkeys
{
public:
virtual ~IHotkeys() = default;

virtual void start() = 0;
virtual void togglePlayPause() = 0;
virtual void next() = 0;
virtual void previous() = 0;
virtual void toggleFavoriteSong() = 0;
virtual void restoreWindow() = 0;
};
}
7 changes: 2 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ add_executable(${PROJECT_NAME} MACOSX_BUNDLE WIN32 ${SOURCE_FILES} ${QM_FILES} $
target_link_libraries(${PROJECT_NAME}
${PROJECT_NAME}.Domain ${PROJECT_NAME}.Presentation ${PROJECT_NAME}.Infrastructure
Qt5::Concurrent Qt5::Core Qt5::Gui Qt5::Network Qt5::Qml Qt5::Quick Qt5::QuickControls2
Qt5::Sql Qt5::Svg Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets)
if (qxtglobalshortcut_FOUND)
target_link_libraries(${PROJECT_NAME} qxtglobalshortcut)
endif()
Qt5::Sql Qt5::Svg Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets qxtglobalshortcut)
if (APPLE)
add_framework(Carbon ${PROJECT_NAME})
add_framework(Cocoa ${PROJECT_NAME})
Expand All @@ -69,7 +66,7 @@ if (WIN32)
target_link_libraries(${PROJECT_NAME}.Console
${PROJECT_NAME}.Domain ${PROJECT_NAME}.Presentation ${PROJECT_NAME}.Infrastructure
Qt5::Concurrent Qt5::Core Qt5::Gui Qt5::Network Qt5::Qml Qt5::Quick Qt5::QuickControls2
Qt5::Sql Qt5::Svg Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets)
Qt5::Sql Qt5::Svg Qt5::WebEngine Qt5::WebEngineWidgets Qt5::Widgets qxtglobalshortcut)
endif()

install(TARGETS ${PROJECT_NAME}
Expand Down
8 changes: 7 additions & 1 deletion src/DI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
#include <MellowPlayer/Presentation/ViewModels/StreamingServices/StreamingServicesControllerViewModel.hpp>
#include <MellowPlayer/Presentation/ViewModels/ThemeViewModel.hpp>
#include <MellowPlayer/Presentation/ViewModels/UpdaterViewModel.hpp>
#include <MellowPlayer/Presentation/Qml/IContextProperties.hpp>
#include <MellowPlayer/Presentation/Qml/ContextProperties.hpp>
#include <MellowPlayer/Presentation/Qml/IQmlApplicationEngine.hpp>
#include <MellowPlayer/Presentation/Qml/QmlApplicationEngine.hpp>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtWebEngine>
Expand Down Expand Up @@ -143,7 +147,9 @@ auto defaultInjector = [](ScopedScope &scope) {
di::bind<ILatestReleaseQuerier>().to<LatestGithubReleaseQuerier>().in(scope),
di::bind<IHttpClient>().to<HttpClient>().in(scope),
di::bind<IFileDownloader>().to<FileDownloader>().in(scope),
di::bind<IUserScriptFactory>().to<UserScriptFactory>().in(scope)
di::bind<IUserScriptFactory>().to<UserScriptFactory>().in(scope),
di::bind<IContextProperties>().to<ContextProperties>().in(scope),
di::bind<IQmlApplicationEngine>().to<QmlApplicationEngine>().in(scope)
);
};

Expand Down
29 changes: 29 additions & 0 deletions tests/UnitTests/Presentation/FakeMainWindow.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <MellowPlayer/Presentation/MainWindow.hpp>

namespace MellowPlayer::Presentation::Tests
{
class FakeMainWindow: public IMainWindow
{
public:
void load() override
{
isLoaded = true;
}

void show() override
{
isShown = true;
}

void hide() override
{
isHidden = true;
}

bool isLoaded = false;
bool isShown = false;
bool isHidden = false;
};
}
Loading

0 comments on commit 7bfc28b

Please sign in to comment.