Initial commit

This commit is contained in:
2024-02-13 17:26:45 -03:00
commit bd93be6424
22 changed files with 533 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
build
compile_commands.json

28
CMakeLists.txt Normal file
View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.19)
set(PROJECT "QuteSpectrometer")
project(${PROJECT} VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Widgets Qml QuickControls2 REQUIRED)
add_executable(${PROJECT}
src/main.cpp
src/resources.qrc
src/Gui/Style/resources.qrc)
target_link_libraries(${PROJECT}
Qt::Widgets
Qt::Qml
Qt::QuickControls2)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set_property(TARGET ${PROJECT} PROPERTY WIN32_EXECUTABLE true)
endif()

30
LICENSE Normal file
View File

@@ -0,0 +1,30 @@
Copyright (c) 2024 Juny
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the disclaimer
below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

7
src/Gui/App.qml Normal file
View File

@@ -0,0 +1,7 @@
pragma Singleton
import QtQuick
QtObject {
id: app
}

22
src/Gui/Splash.qml Normal file
View File

@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Controls
import "PStyle"
import "Login"
Window {
visible: true
width: 640
height: 480
title: Qt.application.displayName
PBackground {
anchors.fill: parent
Login {
anchors.centerIn: parent
}
}
}

View File

@@ -0,0 +1,6 @@
import QtQuick
import "."
Rectangle {
color: PStyle.backColor
}

View File

@@ -0,0 +1,66 @@
import QtQuick
import QtQuick.Controls
import "."
BusyIndicator {
id: control
contentItem: Item {
width: height
height: control.height
Item {
id: item
x: 0
y: 0
width: parent.width
height: parent.height
opacity: control.running ? 1 : 0
Behavior on opacity {
OpacityAnimator {
duration: PStyle.animationDuration
}
}
RotationAnimator {
target: item
running: control.running && control.visible
from: 0
to: 360
loops: Animation.Infinite
duration: PStyle.animationDuration * 12
}
Repeater {
id: repeater
model: 5
Rectangle {
id: delegate
x: item.width / 2 - width / 2
y: item.height / 2 - height / 2
implicitWidth: 8
implicitHeight: 8
radius: width / 2
color: Qt.darker(PStyle.foreColor, 1.2)
required property int index
transform: [
Translate {
y: -Math.min(item.width, item.height) * 0.5 + 5
},
Rotation {
angle: delegate.index / repeater.count * 360
origin.x: 5
origin.y: 5
}
]
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
import QtQuick
import QtQuick.Controls
import "."
GroupBox {
id: root
label: PText {
font: PStyle.getFont(10)
text: root.title
}
background: PBackground {
color: "transparent"
border.color: PStyle.foreColor
border.width: 1
y: parent.topPadding - parent.padding
height: parent.height - parent.topPadding + parent.padding
}
}

View File

@@ -0,0 +1,25 @@
import QtQuick
import Qt5Compat.GraphicalEffects
Image {
id: icon
property string name: ""
property int dimension: 18
property color colorize: PStyle.foreColor
cache: true
asynchronous: true
fillMode: Image.PreserveAspectFit
source: name ? `qrc:/Icons/${name}.svg` : ""
smooth: false
sourceSize.width: name ? dimension : 0
sourceSize.height: name ? dimension : 0
layer.enabled: ! Qt.colorEqual(colorize, "transparent")
layer.effect: ColorOverlay {
color: icon.colorize
cached: icon.cache
}
}

View File

@@ -0,0 +1,23 @@
import QtQuick.Controls
import QtQuick.Layouts
import "."
PRawButton {
id: btn
topPadding: 8
bottomPadding: topPadding
rightPadding: 8
leftPadding: rightPadding
property alias pIcon: icon
contentItem: RowLayout {
property alias buttonText: icon
PIcon {
id: icon
name: ""
}
}
}

View File

@@ -0,0 +1,26 @@
import QtQuick.Layouts
import "."
ColumnLayout {
property alias label: lbl.text
property alias placeholderText: tf.placeholderText
property alias tfText: tf.text
property alias pTf: tf
spacing: 2
signal tfChanged(text: string)
signal tfAccepted()
PText {
id: lbl
font: PStyle.getFont(8)
}
PTextField {
id: tf
Layout.fillWidth: true
onTextEdited: tfChanged(text)
onAccepted: tfAccepted()
}
}

View File

@@ -0,0 +1,86 @@
import QtQuick
import QtQuick.Controls
import "."
Button {
id: btn
hoverEnabled: true
scale: state === "Pressed" ? 0.96 : 1.0
background: PBackground {
id: background
color: btn.enabled ? Qt.darker(PStyle.backColor, 1.8) : Qt.lighter(PStyle.backColor, 2.4)
border.width: 1
border.color: btn.enabled ? PStyle.foreColor : Qt.darker(PStyle.foreColor, 1.4) // Qt.hsva(0, 1, 0.5, 1)
}
states: [
State {
name: "Hovering"
PropertyChanges {
target: background
color: Qt.lighter(PStyle.backColor, 1.6)
}
PropertyChanges {
target: contentItem.buttonText
colorize: Qt.lighter(PStyle.foreColor, 1.2)
}
},
State {
name: "Pressed"
PropertyChanges {
target: background
color: Qt.darker(PStyle.backColor, 3)
}
PropertyChanges {
target: contentItem.buttonText
colorize: Qt.darker(PStyle.foreColor, 2.4)
}
}
]
transitions: [
Transition {
from: ""
to: "Hovering"
ColorAnimation {
duration: PStyle.animationDuration
}
},
Transition {
from: "*"
to: "Pressed"
ColorAnimation {
duration: PStyle.animationDuration
}
}
]
Behavior on scale {
NumberAnimation {
duration: PStyle.animationDuration
easing.type: Easing.InOutQuad
}
}
MouseArea {
enabled: btn.enabled
hoverEnabled: true
anchors.fill: btn
onEntered: {
btn.state = 'Hovering'
cursorShape = Qt.PointingHandCursor
}
onExited: { btn.state = '' }
onClicked: { btn.clicked() }
onPressed: { btn.state = "Pressed" }
onReleased: {
if (containsMouse)
btn.state = "Hovering"
else
btn.state = ""
}
}
}

View File

@@ -0,0 +1,41 @@
import QtQuick
import QtQuick.Controls
import "."
StackView {
pushEnter: Transition {
PropertyAnimation {
property: "opacity"
from: 0
to: 1
duration: PStyle.animationDuration
}
}
pushExit: Transition {
PropertyAnimation {
property: "opacity"
from: 1
to: 0
duration: PStyle.animationDuration
}
}
popEnter: Transition {
PropertyAnimation {
property: "opacity"
from: 0
to: 1
duration: PStyle.animationDuration
}
}
popExit: Transition {
PropertyAnimation {
property: "opacity"
from: 1
to: 0
duration: PStyle.animationDuration
}
}
}

View File

@@ -0,0 +1,25 @@
pragma Singleton
import QtQuick
QtObject {
property color foreColor: Qt.hsva(0, 0, 0.8, 1)
property color foreColorDim: Qt.darker(foreColor, 1.2)
property color backColor: Qt.hsva(0, 0, 0.1, 1)
property color backColorDark: Qt.darker(backColor, 1.2)
property double animationDuration: 100
property font font: Qt.font({
family: "HackGen Console",
pointSize: 12,
})
function getFont(size = 12) {
return Qt.font({
family: "HackGen Console",
pointSize: size,
})
}
}

View File

@@ -0,0 +1,10 @@
import QtQuick
import "."
Text {
id: txt
property alias colorize: txt.color
color: PStyle.foreColor
font: PStyle.font
}

View File

@@ -0,0 +1,22 @@
import QtQuick.Controls
import QtQuick.Layouts
import "."
PRawButton {
id: btn
topPadding: 8
bottomPadding: topPadding
rightPadding: text ? 24 : 8
leftPadding: rightPadding
contentItem: RowLayout {
property alias buttonText: txt
PText {
id: txt
Layout.alignment: Qt.AlignHCenter
text: btn.text
}
}
}

View File

@@ -0,0 +1,19 @@
import QtQuick.Controls
import "."
TextField {
color: PStyle.foreColor
font: PStyle.font
placeholderTextColor: Qt.darker(PStyle.foreColor, 1.8)
padding: 8
background: PBackground {
id: background
color: Qt.darker(PStyle.backColor, 1.8)
border.width: 1
border.color: PStyle.foreColor
}
property alias bBackground: background
}

View File

@@ -0,0 +1 @@
singleton PStyle 1.0 PStyle.qml

View File

@@ -0,0 +1,17 @@
<RCC>
<qresource prefix="/">
<file alias="PStyle/qmldir">PStyle/qmldir</file>
<file alias="PStyle/PStyle.qml">PStyle/PStyle.qml</file>
<file alias="PStyle/PText.qml">PStyle/PText.qml</file>
<file alias="PStyle/PBackground.qml">PStyle/PBackground.qml</file>
<file alias="PStyle/PTextField.qml">PStyle/PTextField.qml</file>
<file alias="PStyle/PInputField.qml">PStyle/PInputField.qml</file>
<file alias="PStyle/PTextButton.qml">PStyle/PTextButton.qml</file>
<file alias="PStyle/PRawButton.qml">PStyle/PRawButton.qml</file>
<file alias="PStyle/PIconButton.qml">PStyle/PIconButton.qml</file>
<file alias="PStyle/PIcon.qml">PStyle/PIcon.qml</file>
<file alias="PStyle/PBusyIndicator.qml">PStyle/PBusyIndicator.qml</file>
<file alias="PStyle/PStackView.qml">PStyle/PStackView.qml</file>
<file alias="PStyle/PGroupBox.qml">PStyle/PGroupBox.qml</file>
</qresource>
</RCC>

1
src/Gui/qmldir Normal file
View File

@@ -0,0 +1 @@
singleton App 1.0 App.qml

42
src/main.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include <iostream>
#include <QApplication>
#include <QGuiApplication>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickStyle>
#include <QQuickWindow>
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
QApplication::setApplicationName("QuteSpectrometer");
QApplication::setApplicationDisplayName("QuteSpectrometer");
QApplication::setApplicationVersion("0.1");
QQuickStyle::setStyle("Fusion");
QApplication app(argc, argv);
QQmlEngine *engine = new QQmlEngine();
QObject::connect(engine, &QQmlEngine::quit, &QApplication::quit);
engine->addImportPath("qrc:/");
QQmlContext *ctx = new QQmlContext(engine->rootContext());
QQmlComponent component(engine, QUrl("qrc:/Splash.qml"));
if (component.isError()) {
for (QQmlError e : component.errors())
qCritical("%s:%d:%d: %s", e.url().toString().toStdString().c_str(),
e.line(), e.column(), e.description().toStdString().c_str());
qFatal("One or more errors have occurred, exiting");
}
component.create(ctx);
int ret = app.exec();
delete ctx;
delete engine;
return ret;
}

12
src/resources.qrc Normal file
View File

@@ -0,0 +1,12 @@
<RCC>
<qresource prefix="/">
<file alias="Splash.qml">Gui/Splash.qml</file>
<file alias="App.qml">Gui/App.qml</file>
<file alias="qmldir">Gui/qmldir</file>
<!-- login -->
<file alias="Login/Login.qml">Gui/Login/Login.qml</file>
<file alias="Login/InstanceInput.qml">Gui/Login/InstanceInput.qml</file>
<file alias="Login/LoadingInfo.qml">Gui/Login/LoadingInfo.qml</file>
</qresource>
</RCC>