Skip to content

Commit 5ced382

Browse files
authored
Merge pull request #50 from scratchcpp/theme_settings
Add theme settings
2 parents 61b4b3e + bc12722 commit 5ced382

34 files changed

+967
-15
lines changed

src/app/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ qt_add_executable(${APP_TARGET}
1010
libraryinfo.h
1111
)
1212

13+
set_source_files_properties(qml/Colors.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
14+
1315
qt_add_qml_module(${APP_TARGET}
1416
URI ScratchCPP
1517
VERSION 1.0
1618
QML_FILES
1719
qml/main.qml
20+
qml/Colors.qml
1821
qml/dialogs/AboutDialog.qml
1922
qml/dialogs/ProjectSettingsDialog.qml
23+
qml/dialogs/PreferencesDialog.qml
2024
)
2125

2226
set(QML_IMPORT_PATH "${QML_IMPORT_PATH};${CMAKE_CURRENT_LIST_DIR}"

src/app/appmenubar.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ AppMenuBar::AppMenuBar(QObject *parent) :
6969
m_editMenu->addItem(m_projectSettingsItem);
7070
connect(m_projectSettingsItem, &MenuItemModel::clicked, this, &AppMenuBar::projectSettingsTriggered);
7171

72+
// Edit -> (separator)
73+
m_editSeparator = new MenuItemModel(m_editMenu);
74+
m_editSeparator->setIsSeparator(true);
75+
m_editMenu->addItem(m_editSeparator);
76+
77+
// Edit -> Preferences
78+
m_preferencesItem = new MenuItemModel(m_editMenu);
79+
m_preferencesItem->setText(tr("Preferences..."));
80+
m_editMenu->addItem(m_preferencesItem);
81+
connect(m_preferencesItem, &MenuItemModel::clicked, this, &AppMenuBar::preferencesTriggered);
82+
7283
// Help menu
7384
m_helpMenu = new MenuModel(m_model);
7485
m_helpMenu->setTitle(tr("&Help"));

src/app/appmenubar.h

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class AppMenuBar : public QObject
5252
void fps60ModeChanged();
5353
void muteChanged();
5454
void projectSettingsTriggered();
55+
void preferencesTriggered();
5556
void aboutAppTriggered();
5657

5758
private:
@@ -72,6 +73,8 @@ class AppMenuBar : public QObject
7273
uicomponents::MenuItemModel *m_fps60ModeItem = nullptr;
7374
uicomponents::MenuItemModel *m_muteItem = nullptr;
7475
uicomponents::MenuItemModel *m_projectSettingsItem = nullptr;
76+
uicomponents::MenuItemModel *m_editSeparator = nullptr;
77+
uicomponents::MenuItemModel *m_preferencesItem = nullptr;
7578

7679
uicomponents::MenuModel *m_helpMenu = nullptr;
7780
uicomponents::MenuItemModel *m_aboutAppItem = nullptr;

src/app/qml/Colors.qml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
pragma Singleton
4+
import QtQuick
5+
import ScratchCPP.Ui
6+
7+
QtObject {
8+
readonly property list<color> darkAccentColors: [
9+
Qt.rgba(0.85, 0.31, 0.33, 1),
10+
Qt.rgba(0.85, 0.62, 0.31, 1),
11+
Qt.rgba(0.85, 0.84, 0.31, 1),
12+
Qt.rgba(0.39, 0.85, 0.31, 1),
13+
Qt.rgba(0.31, 0.75, 0.85, 1),
14+
Qt.rgba(0.32, 0.32, 0.85, 1),
15+
Qt.rgba(0.68, 0.31, 0.85, 1),
16+
]
17+
18+
readonly property list<color> lightAccentColors: [
19+
Qt.rgba(0.75, 0.08, 0.09, 1),
20+
Qt.rgba(0.75, 0.47, 0.08, 1),
21+
Qt.rgba(0.75, 0.74, 0.08, 1),
22+
Qt.rgba(0.17, 0.75, 0.08, 1),
23+
Qt.rgba(0.08, 0.63, 0.75, 1),
24+
Qt.rgba(0.08, 0.08, 0.75, 1),
25+
Qt.rgba(0.54, 0.08, 0.75, 1),
26+
]
27+
28+
readonly property color defaultAccentColor: ThemeEngine.theme == ThemeEngine.DarkTheme ? darkAccentColors[1] : lightAccentColors[1]
29+
}
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
import QtQuick
4+
import QtQuick.Controls
5+
import QtQuick.Layouts
6+
import ScratchCPP.Global
7+
import ScratchCPP.Ui
8+
import ScratchCPP.UiComponents
9+
10+
import ".."
11+
12+
CustomDialog {
13+
title: qsTr("Preferences")
14+
standardButtons: Dialog.Cancel | Dialog.Ok
15+
onOpened: Settings.freeze()
16+
onAccepted: Settings.saveChanges()
17+
onRejected: {
18+
Settings.discardChanges();
19+
ThemeEngine.reloadTheme();
20+
}
21+
22+
QtObject {
23+
id: priv
24+
property int accentColorIndex: -1
25+
}
26+
27+
contentItem: ColumnLayout {
28+
// Themes
29+
Label {
30+
text: qsTr("Themes")
31+
font.pointSize: 14
32+
font.bold: true
33+
}
34+
35+
RowLayout {
36+
RadioButton {
37+
text: qsTr("Light")
38+
checked: ThemeEngine.theme === ThemeEngine.LightTheme
39+
onCheckedChanged: if(checked) ThemeEngine.theme = ThemeEngine.LightTheme
40+
}
41+
42+
RadioButton {
43+
text: qsTr("Dark")
44+
checked: ThemeEngine.theme === ThemeEngine.DarkTheme
45+
onCheckedChanged: if(checked) ThemeEngine.theme = ThemeEngine.DarkTheme
46+
}
47+
}
48+
49+
RowLayout {
50+
Label {
51+
text: qsTr("Accent color:")
52+
}
53+
54+
Repeater {
55+
id: accentColors
56+
model: ThemeEngine.theme == ThemeEngine.DarkTheme ? Colors.darkAccentColors : Colors.lightAccentColors
57+
58+
ColorButton {
59+
required property color modelData
60+
required property int index
61+
color: modelData
62+
checked: {
63+
if(ThemeEngine.accentColor === modelData) {
64+
priv.accentColorIndex = index;
65+
return true;
66+
} else {
67+
return false;
68+
}
69+
}
70+
autoExclusive: true
71+
checkable: true
72+
onPressed: ThemeEngine.accentColor = modelData;
73+
}
74+
}
75+
}
76+
77+
Connections {
78+
target: ThemeEngine
79+
80+
function onThemeChanged() {
81+
console.log(priv.accentColorIndex, ThemeEngine.theme);
82+
83+
if(ThemeEngine.theme == ThemeEngine.DarkTheme) {
84+
ThemeEngine.accentColor = Colors.darkAccentColors[priv.accentColorIndex];
85+
} else {
86+
ThemeEngine.accentColor = Colors.lightAccentColors[priv.accentColorIndex];
87+
}
88+
}
89+
}
90+
}
91+
}

src/app/qml/main.qml

+13-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ ApplicationWindow {
1717
visible: true
1818
title: Qt.application.displayName
1919
color: Material.background
20-
Material.accent: "orange"
21-
Material.theme: Material.Dark
20+
Material.accent: ThemeEngine.accentColor
21+
Material.theme: ThemeEngine.theme == ThemeEngine.DarkTheme ? Material.Dark : Material.Light
2222
onActiveFocusItemChanged: UiEngine.activeFocusItem = activeFocusItem
2323

2424
menuBar: CustomMenuBar {
@@ -44,6 +44,10 @@ ApplicationWindow {
4444
projectSettingsDialog.open();
4545
}
4646

47+
function onPreferencesTriggered() {
48+
preferencesDialog.open();
49+
}
50+
4751
function onAboutAppTriggered() {
4852
aboutDialog.open();
4953
}
@@ -57,6 +61,8 @@ ApplicationWindow {
5761
projectPlayer: player
5862
}
5963

64+
PreferencesDialog { id: preferencesDialog }
65+
6066
CustomMessageDialog {
6167
id: unsupportedBlocksDialog
6268
title: qsTr("Warning")
@@ -166,4 +172,9 @@ ApplicationWindow {
166172
}
167173
}
168174
}
175+
176+
Component.onCompleted: {
177+
if(ThemeEngine.accentColor === Qt.rgba(0, 0, 0, 0))
178+
ThemeEngine.accentColor = Colors.defaultAccentColor;
179+
}
169180
}

src/global/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ set(MODULE_SRC
44
globalmodule.cpp
55
globalmodule.h
66
iappinfo.h
7+
ifilepaths.h
8+
isettings.h
79
modularity/ioc.h
810
modularity/modulesioc.h
911
modularity/imoduleexportinterface.h
1012
modularity/imodulesetup.h
1113
internal/appinfo.cpp
1214
internal/appinfo.h
15+
internal/filepaths.cpp
16+
internal/filepaths.h
17+
internal/settings.cpp
18+
internal/settings.h
1319
)
1420

1521
include(${PROJECT_SOURCE_DIR}/build/module.cmake)

src/global/globalmodule.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "globalmodule.h"
66
#include "internal/appinfo.h"
7+
#include "internal/filepaths.h"
8+
#include "internal/settings.h"
79

810
using namespace scratchcpp;
911

@@ -19,4 +21,12 @@ void GlobalModule::registerExports()
1921
QQmlEngine::setObjectOwnership(m_appInfo.get(), QQmlEngine::CppOwnership);
2022
qmlRegisterSingletonInstance<AppInfo>("ScratchCPP.Ui", 1, 0, "AppInfo", m_appInfo.get());
2123
modularity::ioc()->registerExport<IAppInfo>(m_appInfo);
24+
25+
modularity::ioc()->registerExport<FilePaths>(FilePaths::instance());
26+
27+
m_settings = std::make_shared<Settings>();
28+
29+
QQmlEngine::setObjectOwnership(m_settings.get(), QQmlEngine::CppOwnership);
30+
qmlRegisterSingletonInstance<Settings>("ScratchCPP.Global", 1, 0, "Settings", m_settings.get());
31+
modularity::ioc()->registerExport<Settings>(m_settings);
2232
}

src/global/globalmodule.h

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace scratchcpp
1010
{
1111

1212
class AppInfo;
13+
class Settings;
1314

1415
class GlobalModule : public modularity::IModuleSetup
1516
{
@@ -20,6 +21,7 @@ class GlobalModule : public modularity::IModuleSetup
2021

2122
private:
2223
std::shared_ptr<AppInfo> m_appInfo;
24+
std::shared_ptr<Settings> m_settings;
2325
};
2426

2527
} // namespace scratchcpp

src/global/ifilepaths.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include <QString>
6+
7+
#include "modularity/ioc.h"
8+
9+
namespace scratchcpp
10+
{
11+
12+
class IFilePaths : MODULE_EXPORT_INTERFACE
13+
{
14+
public:
15+
virtual ~IFilePaths() { }
16+
17+
virtual QString configLocation() const = 0;
18+
};
19+
20+
} // namespace scratchcpp

src/global/internal/filepaths.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
#include <QStandardPaths>
4+
#include <QCoreApplication>
5+
6+
#include "filepaths.h"
7+
8+
using namespace scratchcpp;
9+
10+
std::shared_ptr<FilePaths> FilePaths::m_instance = std::make_shared<FilePaths>();
11+
12+
std::shared_ptr<FilePaths> FilePaths::instance()
13+
{
14+
return m_instance;
15+
}
16+
17+
QString scratchcpp::FilePaths::configLocation() const
18+
{
19+
return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + qApp->applicationName() + "/config.ini";
20+
}

src/global/internal/filepaths.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include <QObject>
6+
7+
#include "ifilepaths.h"
8+
9+
namespace scratchcpp
10+
{
11+
12+
class FilePaths : public IFilePaths
13+
{
14+
public:
15+
static std::shared_ptr<FilePaths> instance();
16+
17+
QString configLocation() const override;
18+
19+
private:
20+
static std::shared_ptr<FilePaths> m_instance;
21+
};
22+
23+
} // namespace scratchcpp

0 commit comments

Comments
 (0)