Skip to content
5 changes: 3 additions & 2 deletions build/module_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ if (SCRATCHCPP_PLAYER_BUILD_UNIT_TESTS)
${MODULE}
GTest::gtest_main
GTest::gmock_main
Qt6::Gui
Qt6::Qml
${QT_LIBS}
Qt6::Test
)

target_include_directories(${TARGET} PRIVATE ${MODULE_SRC_DIR})
target_include_directories(${TARGET} PRIVATE ${PROJECT_SOURCE_DIR}/src)
target_include_directories(${TARGET} PRIVATE ${PROJECT_SOURCE_DIR}/src/global)
gtest_discover_tests(${TARGET})
endif()
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_subdirectory(app)

add_subdirectory(global)
add_subdirectory(ui)
add_subdirectory(uicomponents)
add_subdirectory(keyboard)
4 changes: 3 additions & 1 deletion src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ qt_add_executable(${APP_TARGET}
qt_add_qml_module(${APP_TARGET}
URI ScratchCPP
VERSION 1.0
QML_FILES main.qml
QML_FILES
qml/main.qml
qml/dialogs/AboutDialog.qml
)

set(QML_IMPORT_PATH "${QML_IMPORT_PATH};${CMAKE_CURRENT_LIST_DIR}"
Expand Down
5 changes: 4 additions & 1 deletion src/app/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "app.h"
#include "globalmodule.h"
#include "modularity/ioc.h"
#include "ui/internal/uiengine.h"

using namespace scratchcpp;
using namespace scratchcpp::modularity;
Expand Down Expand Up @@ -65,7 +66,7 @@ int App::run(int argc, char **argv)
QQmlApplicationEngine engine;
engine.addImportPath(":/");

const QUrl url(u"qrc:/ScratchCPP/main.qml"_qs);
const QUrl url(u"qrc:/ScratchCPP/qml/main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
Expand All @@ -77,6 +78,8 @@ int App::run(int argc, char **argv)
Qt::QueuedConnection);
engine.load(url);

ui::UiEngine::instance()->setQmlEngine(&engine);

// Run the event loop
int exitCode = app.exec();

Expand Down
11 changes: 11 additions & 0 deletions src/app/appmenubar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ AppMenuBar::AppMenuBar(QObject *parent) :
m_fps60ModeItem->setChecked(false);
m_editMenu->addItem(m_fps60ModeItem);
connect(m_fps60ModeItem, &MenuItemModel::checkedChanged, this, &AppMenuBar::fps60ModeChanged);

// Help menu
m_helpMenu = new MenuModel(m_model);
m_helpMenu->setTitle(tr("&Help"));
m_model->addMenu(m_helpMenu);

// Help -> About program
m_aboutAppItem = new MenuItemModel(m_fileMenu);
m_aboutAppItem->setText(tr("About program..."));
m_helpMenu->addItem(m_aboutAppItem);
connect(m_aboutAppItem, &MenuItemModel::clicked, this, &AppMenuBar::aboutAppTriggered);
}

MenuBarModel *AppMenuBar::model() const
Expand Down
4 changes: 4 additions & 0 deletions src/app/appmenubar.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class AppMenuBar : public QObject
void fileOpened(const QString &fileName);
void turboModeChanged();
void fps60ModeChanged();
void aboutAppTriggered();

private:
void openFile();
Expand All @@ -63,6 +64,9 @@ class AppMenuBar : public QObject
uicomponents::MenuModel *m_editMenu = nullptr;
uicomponents::MenuItemModel *m_turboModeItem = nullptr;
uicomponents::MenuItemModel *m_fps60ModeItem = nullptr;

uicomponents::MenuModel *m_helpMenu = nullptr;
uicomponents::MenuItemModel *m_aboutAppItem = nullptr;
};

} // namespace scratchcpp
2 changes: 2 additions & 0 deletions src/app/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include "app.h"
#include "ui/uimodule.h"
#include "uicomponents/uicomponentsmodule.h"
#include "keyboard/keyboardmodule.h"

Expand All @@ -9,6 +10,7 @@ using namespace scratchcpp;
int main(int argc, char *argv[])
{
App app;
app.addModule(new ui::UiModule);
app.addModule(new uicomponents::UiComponentsModule);
app.addModule(new keyboard::KeyboardModule);

Expand Down
Empty file added src/app/qml/CMakeLists.txt
Empty file.
59 changes: 59 additions & 0 deletions src/app/qml/dialogs/AboutDialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import ScratchCPP.Ui
import ScratchCPP.UiComponents

CustomDialog {
//: For example "About ScratchCPP" (%1 is the app name)
title: qsTr("About %1").arg(Qt.application.displayName)
standardButtons: Dialog.Ok

contentItem: RowLayout {
spacing: 25

/*Image {
source: "qrc:/res/images/icon.ico"
sourceSize.width: 60
sourceSize.height: 60
Layout.alignment: Qt.AlignTop
}*/

ColumnLayout {
Label {
text: Qt.application.displayName
font.bold: true
}

Label {}

Label {
text: qsTr("Version: %1").arg(Qt.application.version)
}

Label {
text: qsTr("Revision: %1").arg(AppInfo.revision())
}

Label {
readonly property string src: "https://github.com/scratchcpp/scratchcpp-player"
text: qsTr("Source code: %1").arg("<a href=\"" + src + "\">" + src + "</a>")
onLinkActivated: (link)=> Qt.openUrlExternally(link)
}

Label {}

Label {
readonly property int startYear: 2024
readonly property string startStr: AppInfo.buildYear() === startYear ? "" : startYear + "-"
text: "Copyright © " + startStr + AppInfo.buildYear() + " adazem009"
}

Label {
text: qsTr("Published with the GNU General Public License.")
}
}
}
}
9 changes: 9 additions & 0 deletions src/app/main.qml → src/app/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import ScratchCPP
import ScratchCPP.Ui
import ScratchCPP.UiComponents
import ScratchCPP.Render
import ScratchCPP.Keyboard
import "dialogs"

ApplicationWindow {
id: root
Expand All @@ -17,6 +19,7 @@ ApplicationWindow {
color: Material.background
Material.accent: "orange"
Material.theme: Material.Dark
onActiveFocusItemChanged: UiEngine.activeFocusItem = activeFocusItem

menuBar: CustomMenuBar {
width: root.width
Expand All @@ -29,9 +32,15 @@ ApplicationWindow {
urlField.text = fileName;
player.fileName = fileName;
}

function onAboutAppTriggered() {
aboutDialog.open();
}
}
}

AboutDialog { id: aboutDialog }

ColumnLayout {
id: layout
anchors.fill: parent
Expand Down
14 changes: 14 additions & 0 deletions src/global/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,26 @@ set(MODULE_URI Global)
set(MODULE_SRC
globalmodule.cpp
globalmodule.h
iappinfo.h
modularity/ioc.h
modularity/modulesioc.h
modularity/imoduleexportinterface.h
modularity/imodulesetup.h
internal/appinfo.cpp
internal/appinfo.h
)

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

include(FetchContent)
FetchContent_Declare(cmake_git_version_tracking
GIT_REPOSITORY https://github.com/andrew-hardin/cmake-git-version-tracking.git
GIT_TAG 904dbda1336ba4b9a1415a68d5f203f576b696bb
)
FetchContent_MakeAvailable(cmake_git_version_tracking)

target_link_libraries(${MODULE} PRIVATE cmake_git_version_tracking)
string(TIMESTAMP BUILD_YEAR "%Y")
target_compile_definitions(${MODULE} PRIVATE BUILD_YEAR=${BUILD_YEAR})

add_subdirectory(test)
12 changes: 12 additions & 0 deletions src/global/globalmodule.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QQmlEngine>

#include "globalmodule.h"
#include "internal/appinfo.h"

using namespace scratchcpp;

std::string GlobalModule::moduleName() const
{
return "global";
}

void GlobalModule::registerExports()
{
m_appInfo = std::make_shared<AppInfo>();

QQmlEngine::setObjectOwnership(m_appInfo.get(), QQmlEngine::CppOwnership);
qmlRegisterSingletonInstance<AppInfo>("ScratchCPP.Ui", 1, 0, "AppInfo", m_appInfo.get());
modularity::ioc()->registerExport<IAppInfo>(m_appInfo);
}
9 changes: 9 additions & 0 deletions src/global/globalmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@

#pragma once

#include <memory>

#include "modularity/imodulesetup.h"

namespace scratchcpp
{

class AppInfo;

class GlobalModule : public modularity::IModuleSetup
{
public:
std::string moduleName() const override;

void registerExports() override;

private:
std::shared_ptr<AppInfo> m_appInfo;
};

} // namespace scratchcpp
21 changes: 21 additions & 0 deletions src/global/iappinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include "modularity/ioc.h"

class QString;

namespace scratchcpp
{

class IAppInfo : MODULE_EXPORT_INTERFACE
{
public:
virtual ~IAppInfo() { }

virtual QString revision() const = 0;
virtual int buildYear() const = 0;
};

} // namespace scratchcpp
22 changes: 22 additions & 0 deletions src/global/internal/appinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <git.h>

#include "appinfo.h"

using namespace scratchcpp;

AppInfo::AppInfo(QObject *parent) :
QObject(parent)
{
}

QString scratchcpp::AppInfo::revision() const
{
return git_CommitSHA1();
}

int scratchcpp::AppInfo::buildYear() const
{
return BUILD_YEAR;
}
24 changes: 24 additions & 0 deletions src/global/internal/appinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QObject>

#include "iappinfo.h"

namespace scratchcpp
{

class AppInfo
: public QObject
, public IAppInfo
{
Q_OBJECT
public:
explicit AppInfo(QObject *parent = nullptr);

Q_INVOKABLE QString revision() const override;
Q_INVOKABLE int buildYear() const override;
};

} // namespace scratchcpp
6 changes: 6 additions & 0 deletions src/global/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
set(MODULE_TEST_SRC
modularity.cpp
setup.cpp
appinfo.cpp
fakeexport.h
fakedependency.h
mocks/moduleexportinterfacemock.h
mocks/modulesetupmock.h
)

include(${PROJECT_SOURCE_DIR}/build/module_test.cmake)

set(TARGET ${MODULE}_test)
target_link_libraries(${TARGET} cmake_git_version_tracking)
string(TIMESTAMP BUILD_YEAR "%Y")
target_compile_definitions(${TARGET} PRIVATE BUILD_YEAR=${BUILD_YEAR})
25 changes: 25 additions & 0 deletions src/global/test/appinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <gtest/gtest.h>
#include <QDebug>

#include "internal/appinfo.h"

// Workaround for multiple definition error
namespace scratchcpp::test
{
#include <git.h>
}

using namespace scratchcpp;
using namespace scratchcpp::test;

TEST(AppInfoTest, Revision)
{
AppInfo info;
ASSERT_EQ(info.revision(), git_CommitSHA1());
}

TEST(AppInfoTest, BuildYear)
{
AppInfo info;
ASSERT_EQ(info.buildYear(), BUILD_YEAR);
}
Loading