diff --git a/.gitignore b/.gitignore index c2cb1ee..d5095c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ Scorganizr.pyproject.user* +CMakeLists.txt.user +build*/ __pycache__/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6ccd23f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16) + +project(Scorganizr VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(appScorganizr + main.cpp +) + +qt_add_qml_module(appScorganizr + URI Scorganizr + VERSION 1.0 + QML_FILES Main.qml SiteInConstruction.qml Icon.qml +) + +set_target_properties(appScorganizr PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(appScorganizr + PRIVATE Qt6::Quick +) + +install(TARGETS appScorganizr + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Icon.qml b/Icon.qml new file mode 100644 index 0000000..34abbe5 --- /dev/null +++ b/Icon.qml @@ -0,0 +1,21 @@ +import QtQuick +import Qt5Compat.GraphicalEffects + +Image { + id: icon + + property string color: "" + property string path: "" + + fillMode: Image.PreserveAspectFit + source: path + + layer{ + enabled: color != "" + effect: ColorOverlay { + color: icon.color + } + } + + sourceSize: Qt.size(width*3, height*3) // for better resolution when loading svg files +} diff --git a/Main.qml b/Main.qml new file mode 100644 index 0000000..cf27bff --- /dev/null +++ b/Main.qml @@ -0,0 +1,66 @@ +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Controls.Material + +ApplicationWindow { + width: Screen.width/2 + height: Screen.height/2 + visible: true + title: "Scorganizr" + + Material.theme: Material.System + Material.accent: Material.Pink + + Page { + id: window + anchors.fill: parent + + Keys.onPressed: (event)=> { + if (event.key === Qt.Key_1) tabBar.currentIndex = 0; + if (event.key === Qt.Key_2) tabBar.currentIndex = 1; + if (event.key === Qt.Key_3) tabBar.currentIndex = 2; + if (event.key === Qt.Key_4) tabBar.currentIndex = 3; + if (event.key === Qt.Key_5) tabBar.currentIndex = 4; + } + focus: true + + SwipeView { + id: swipeView + anchors.fill: parent + currentIndex: tabBar.currentIndex + + Repeater { + model: 5 + + Pane { + width: SwipeView.view.width + height: SwipeView.view.height + + SiteInConstruction {} + } + } + } + + footer: TabBar { + id: tabBar + currentIndex: swipeView.currentIndex + + TabButton { + text: qsTr("Notes") + } + TabButton { + text: qsTr("Grades") + } + TabButton { + text: qsTr("Tasks") + } + TabButton { + text: qsTr("Calendar") + } + TabButton { + text: qsTr("Learn") + } + } + } +} diff --git a/Scorganizr.pyproject b/Scorganizr.pyproject deleted file mode 100644 index d38a669..0000000 --- a/Scorganizr.pyproject +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files": ["main.ui","main.py","utils.py"] -} diff --git a/SiteInConstruction.qml b/SiteInConstruction.qml new file mode 100644 index 0000000..c7381a4 --- /dev/null +++ b/SiteInConstruction.qml @@ -0,0 +1,39 @@ +import QtQuick +import QtQuick.Controls.Material + +Item { + id: siteInConstruction + anchors.fill: parent + property string inDevIconDataURI: `data:image/svg+xml;utf8, + + + ` + property string subtitle: "" + + // workaround to prevent the error "Point size [...] must be greater than 0" + function getFontSize(s) { + return s === 0 ? 1 : s; + } + + children: [ + Icon { + id: inDevIcon + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + path: parent.inDevIconDataURI + width: parent.width/5 + height: width + color: "white" + }, + Text { + id: inDevText + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: inDevIcon.bottom + anchors.margins: inDevIcon.width/10 + font.pointSize: getFontSize(inDevIcon.width/8) + text: "Site in construction!" + color: Material.foreground + } + ] +} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..7b1c406 --- /dev/null +++ b/main.cpp @@ -0,0 +1,18 @@ +#include +#include + + +int main(int argc, char *argv[]) +{ + qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load( QUrl("qrc:/Scorganizr/Main.qml") ); + + return app.exec(); +} diff --git a/main.py b/main.py deleted file mode 100644 index 5283fe5..0000000 --- a/main.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -Main application -Copyright (C) 2023 Benjamin Burkhardt - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - -import sys -from PySide6.QtWidgets import QApplication -from PySide6.QtCore import QFile, QIODevice -from PySide6.QtUiTools import QUiLoader -from utils import Logger - - -if __name__ == "__main__": - # needed variables - app = QApplication(sys.argv) - logger = Logger() - ui_file_name = "main.ui" - - # create the window - ui_file = QFile(ui_file_name) - if not ui_file.open(QIODevice.ReadOnly): - logger.log(f"Cannot open {ui_file_name}: {ui_file.errorString()}. Exiting.", 1) - sys.exit(-1) - window = QUiLoader().load(ui_file) - ui_file.close() - if not window: - logger.log(loader.errorString(), 1) - sys.exit(-1) - window.show() - - # run as long as the app is executing - sys.exit(app.exec()) diff --git a/main.ui b/main.ui deleted file mode 100644 index 47be1e7..0000000 --- a/main.ui +++ /dev/null @@ -1,84 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 718 - 408 - - - - Scorganizr - - - - .. - - - true - - - false - - - QTabWidget::Rounded - - - - - - 0 - 0 - 718 - 20 - - - - - false - - - File - - - false - - - false - - - - - - - - Quit - - - Ctrl+Q - - - - - - - actionQuit - triggered() - MainWindow - close() - - - -1 - -1 - - - 358 - 203 - - - - - diff --git a/utils.py b/utils.py deleted file mode 100644 index 9f96da7..0000000 --- a/utils.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -Utility classes and functions -Copyright (C) 2023 Benjamin Burkhardt - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - - -# Logger class that has 7 log levels: trace/all (6), debug (5), info(4), warning (3), error (2), fatal (1), off (0) -# log "level" -1 is always printed out ("On") - -LOG_LVL_FALLBACK = 4 # the default level for logging - -class Logger: - def __init__(self, log_level=LOG_LVL_FALLBACK): - self.mappings = { # mappings for the color and syntax of the log - -1: { - "prefix": "", - "space_between": "", - "prefix_colors": ShellColors.F_Default + ShellColors.B_Default, - "text_colors": ShellColors.F_Default + ShellColors.B_Default, - }, - 1: { - "prefix": "[FATAL]", - "space_between": " ", - "prefix_colors": ShellColors.F_White + ShellColors.B_Red, - "text_colors": ShellColors.B_Red + ShellColors.F_White, - }, - 2: { - "prefix": "[ERROR]", - "space_between": " ", - "prefix_colors": ShellColors.F_White + ShellColors.B_Red, - "text_colors": ShellColors.B_Red + ShellColors.F_White, - }, - 3: { - "prefix": "[WARN]", - "space_between": " ", - "prefix_colors": ShellColors.F_LightRed + ShellColors.B_Default, - "text_colors": ShellColors.F_Default + ShellColors.B_Default, - }, - 4: { - "prefix": "[INFO]", - "space_between": " ", - "prefix_colors": ShellColors.F_Green + ShellColors.B_Default, - "text_colors": ShellColors.F_Default + ShellColors.B_Default, - }, - 5: { - "prefix": "[DEBUG]", - "space_between": " ", - "prefix_colors": ShellColors.F_LightGray + ShellColors.B_Default, - "text_colors": ShellColors.F_Default + ShellColors.B_Default, - }, - 6: { - "prefix": "[TRACE]", - "space_between": " ", - "prefix_colors": ShellColors.F_Default + ShellColors.B_Default, - "text_colors": ShellColors.F_Default + ShellColors.B_Default, - }, - } - - if -1 <= log_level <= 6: - self.log_level = log_level - else: # if the given level exeeds the allowed scope - self.log_level = LOG_LVL_FALLBACK - self.log(f"The log level exeeds the allowed scope. Defaulting to {LOG_LVL_FALLBACK}", 3) - - def log(self, message, log_level=4): - if log_level <= self.log_level: # only log when supposed to (if the given lvl is lower/equal (than) the maximum wanted) - prefix_colors = self.mappings[log_level]['prefix_colors'] - prefix = self.mappings[log_level]['prefix'] - space_between = self.mappings[log_level]['space_between'] - text_colors = self.mappings[log_level]['text_colors'] - end_color = ShellColors.Reset - print(f"{prefix_colors}{prefix}{text_colors}{space_between}{message}{end_color}") - - -# just for prettier shell outputs (especially log) -# source: https://stackoverflow.com/questions/39473297/how-do-i-print-colored-output-with-python-3 -class ShellColors: - # Foreground - F_Default = "\x1b[39m" - F_Black = "\x1b[30m" - F_Red = "\x1b[31m" - F_Green = "\x1b[32m" - F_Yellow = "\x1b[33m" - F_Blue = "\x1b[34m" - F_Magenta = "\x1b[35m" - F_Cyan = "\x1b[36m" - F_LightGray = "\x1b[37m" - F_DarkGray = "\x1b[90m" - F_LightRed = "\x1b[91m" - F_LightGreen = "\x1b[92m" - F_LightYellow = "\x1b[93m" - F_LightBlue = "\x1b[94m" - F_LightMagenta = "\x1b[95m" - F_LightCyan = "\x1b[96m" - F_White = "\x1b[97m" - # Background - B_Default = "\x1b[49m" - B_Black = "\x1b[40m" - B_Red = "\x1b[41m" - B_Green = "\x1b[42m" - B_Yellow = "\x1b[43m" - B_Blue = "\x1b[44m" - B_Magenta = "\x1b[45m" - B_Cyan = "\x1b[46m" - B_LightGray = "\x1b[47m" - B_DarkGray = "\x1b[100m" - B_LightRed = "\x1b[101m" - B_LightGreen = "\x1b[102m" - B_LightYellow = "\x1b[103m" - B_LightBlue = "\x1b[104m" - B_LightMagenta = "\x1b[105m" - B_LightCyan = "\x1b[106m" - B_White = "\x1b[107m" - # Formatting - Bold = "\x1b[1m" - Dim = "\x1b[2m" - Italic = "\x1b[3m" - Underlined = "\x1b[4m" - Blink = "\x1b[5m" - Reverse = "\x1b[7m" - Hidden = "\x1b[8m" - # Reset part - Reset = "\x1b[0m" - Reset_Bold = "\x1b[21m" - Reset_Dim = "\x1b[22m" - Reset_Italic = "\x1b[23m" - Reset_Underlined = "\x1b[24" - Reset_Blink = "\x1b[25m" - Reset_Reverse = "\x1b[27m" - Reset_Hidden = "\x1b[28m"