ff4ff35918
Red Bear OS is a full fork. All sources must be available from git clone with zero network access. Removed gitignore rules that excluded fetched source trees under recipes/*/source/, local/recipes/kde/*/source/, local/recipes/qt/*/source/, and vendor source trees. Build artifacts (target/, build/, source.tar, *.o, *.so) remain excluded. 127291 files added — kernel, relibc, base, bootloader, pkgar, all KDE/Qt frameworks, mesa, wayland, DRM drivers, and every other recipe source.
355 lines
12 KiB
QML
355 lines
12 KiB
QML
// Copyright (C) 2023 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
import QtQuick
|
|
import QtQuick3D
|
|
import QtQuick3D.Particles3D
|
|
|
|
Item {
|
|
id: mainWindow
|
|
|
|
readonly property real meterTicksAngle: 300
|
|
readonly property bool particleNeedle: checkBoxParticlesNeedle.checked
|
|
property real separation: sliderElementSeparation.sliderValue
|
|
|
|
anchors.fill: parent
|
|
|
|
Behavior on separation {
|
|
SmoothedAnimation {
|
|
velocity: 0.2
|
|
duration: 1000
|
|
}
|
|
}
|
|
|
|
View3D {
|
|
id: view3D
|
|
anchors.fill: parent
|
|
|
|
environment: SceneEnvironment {
|
|
clearColor: "#161610"
|
|
backgroundMode: SceneEnvironment.Color
|
|
antialiasingMode: AppSettings.antialiasingMode
|
|
antialiasingQuality: AppSettings.antialiasingQuality
|
|
}
|
|
|
|
PerspectiveCamera {
|
|
position: Qt.vector3d(0, 100, 600 - mainWindow.separation * 100)
|
|
}
|
|
|
|
PointLight {
|
|
position: Qt.vector3d(200, 400, 300)
|
|
brightness: 5
|
|
ambientColor: Qt.rgba(0.3, 0.3, 0.3, 1.0)
|
|
}
|
|
|
|
// Background
|
|
Model {
|
|
source: "#Rectangle"
|
|
scale: Qt.vector3d(25, 15, 0)
|
|
z: -300
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#505040"
|
|
}
|
|
}
|
|
|
|
Node {
|
|
id: speedometerComponent
|
|
|
|
position: Qt.vector3d(0, 100, 0)
|
|
eulerRotation.x: 90 - mainWindow.separation * 75
|
|
|
|
// Light which follows the needle
|
|
PointLight {
|
|
// Calculates the direction of the needle
|
|
function getNeedleAngle(startAngle) {
|
|
return Math.sin(startAngle +
|
|
(-(180 / 360) +
|
|
(-gaugeItem.value * mainWindow.meterTicksAngle / 360) +
|
|
(mainWindow.meterTicksAngle / 2 + 180) / 360) * 2 * Math.PI);
|
|
}
|
|
|
|
readonly property real lightRadius: 120
|
|
readonly property real posX: getNeedleAngle(Math.PI) * lightRadius
|
|
readonly property real posY: getNeedleAngle(Math.PI / 2) * lightRadius
|
|
|
|
position: Qt.vector3d(posX, 40, -posY)
|
|
color: Qt.rgba(1.0, 0.8, 0.4, 1.0)
|
|
brightness: sliderNeedleBrightness.sliderValue
|
|
quadraticFade: 4.0
|
|
}
|
|
|
|
Model {
|
|
y: -4 - mainWindow.separation * 100
|
|
source: "meshes/meter_background.mesh"
|
|
scale: Qt.vector3d(30, 30, 30)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#505050"
|
|
metalness: 1.0
|
|
roughness: 0.6
|
|
normalMap: Texture {
|
|
source: "images/leather_n.png"
|
|
}
|
|
normalStrength: 0.4
|
|
}
|
|
}
|
|
Model {
|
|
y: -35 - mainWindow.separation * 100
|
|
source: "#Sphere"
|
|
scale: Qt.vector3d(1.6, 0.2, 1.6)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#606060"
|
|
}
|
|
}
|
|
Model {
|
|
y: -mainWindow.separation * 60
|
|
source: "#Cylinder"
|
|
scale: Qt.vector3d(0.2, 0.8, 0.2)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#606060"
|
|
}
|
|
}
|
|
Model {
|
|
y: 30 - mainWindow.separation * 60
|
|
source: "#Sphere"
|
|
scale: Qt.vector3d(0.4, 0.1, 0.4)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#f0f0f0"
|
|
}
|
|
}
|
|
|
|
// Speedometer labels
|
|
Model {
|
|
y: 25 + mainWindow.separation * 20
|
|
source: "#Rectangle"
|
|
scale: Qt.vector3d(4, 4, 4)
|
|
eulerRotation.x: -90
|
|
materials: PrincipledMaterial {
|
|
alphaMode: PrincipledMaterial.Blend
|
|
baseColorMap: Texture {
|
|
source: "images/speedometer_labels.png"
|
|
}
|
|
}
|
|
}
|
|
|
|
Model {
|
|
y: mainWindow.separation * 60
|
|
source: "meshes/meter_edge.mesh"
|
|
scale: Qt.vector3d(30, 30, 30)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#b0b0b0"
|
|
}
|
|
}
|
|
|
|
Node {
|
|
id: gaugeItem
|
|
|
|
property real value: 0
|
|
property real needleSize: 180
|
|
|
|
SequentialAnimation {
|
|
running: checkBoxAnimateSpeed.checked
|
|
loops: Animation.Infinite
|
|
NumberAnimation {
|
|
target: gaugeItem
|
|
property: "value"
|
|
duration: 8000
|
|
to: 1
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
NumberAnimation {
|
|
target: gaugeItem
|
|
property: "value"
|
|
duration: 8000
|
|
to: 0
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
y: 20 - mainWindow.separation * 60
|
|
eulerRotation.z: 90
|
|
eulerRotation.y: -mainWindow.meterTicksAngle * value + (mainWindow.meterTicksAngle/2 - 90)
|
|
|
|
Model {
|
|
position.y: gaugeItem.needleSize / 2
|
|
source: "#Cylinder"
|
|
scale: Qt.vector3d(0.05, gaugeItem.needleSize * 0.01, 0.2)
|
|
materials: PrincipledMaterial {
|
|
baseColor: "#606060"
|
|
opacity: mainWindow.particleNeedle ? 0.0 : 1.0
|
|
}
|
|
|
|
ParticleEmitter3D {
|
|
system: psystemGauge
|
|
particle: particleSpark
|
|
y: 10
|
|
scale: Qt.vector3d(0.1, 0.8, 0.1)
|
|
shape: ParticleShape3D {
|
|
type: ParticleShape3D.Cube
|
|
}
|
|
particleScale: 2.0
|
|
particleScaleVariation: 1.0
|
|
particleRotationVariation: Qt.vector3d(0, 0, 180)
|
|
particleRotationVelocityVariation: Qt.vector3d(20, 20, 200);
|
|
emitRate: 500
|
|
lifeSpan: 2000
|
|
lifeSpanVariation: 1000
|
|
}
|
|
|
|
// Needle particle system
|
|
// This system rotates together with the needle
|
|
ParticleSystem3D {
|
|
id: psystemNeedle
|
|
running: mainWindow.particleNeedle
|
|
visible: running
|
|
SpriteParticle3D {
|
|
id: needleParticle
|
|
sprite: Texture {
|
|
source: "images/dot.png"
|
|
}
|
|
maxAmount: 500
|
|
fadeInDuration: 50
|
|
fadeOutDuration: 200
|
|
color: "#40808020"
|
|
colorVariation: Qt.vector4d(0.2, 0.2, 0.0, 0.2)
|
|
blendMode: SpriteParticle3D.Screen
|
|
}
|
|
|
|
ParticleEmitter3D {
|
|
particle: needleParticle
|
|
y: -50
|
|
scale: Qt.vector3d(0.2, 0.0, 0.2)
|
|
shape: ParticleShape3D {
|
|
type: ParticleShape3D.Cube
|
|
}
|
|
|
|
particleScale: 4.0
|
|
particleScaleVariation: 2.0
|
|
particleEndScale: 1.0
|
|
particleEndScaleVariation: 0.5
|
|
velocity: VectorDirection3D {
|
|
direction: Qt.vector3d(0, 110, 0)
|
|
directionVariation: Qt.vector3d(10, 10, 10)
|
|
}
|
|
emitRate: sliderNeedleEmitrate.sliderValue
|
|
lifeSpan: 1000
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Gauge particle system
|
|
ParticleSystem3D {
|
|
id: psystemGauge
|
|
// Particles coming under the needle
|
|
SpriteParticle3D {
|
|
id: particleSpark
|
|
sprite: Texture {
|
|
source: "images/star3.png"
|
|
}
|
|
maxAmount: 1500
|
|
fadeInEffect: SpriteParticle3D.FadeNone
|
|
fadeOutDuration: 200
|
|
color: "#40ff0000"
|
|
colorVariation: Qt.vector4d(0.4, 0.2, 0.2, 0.2)
|
|
unifiedColorVariation: true
|
|
blendMode: SpriteParticle3D.Screen
|
|
}
|
|
// Particles rotating the gauge
|
|
SpriteParticle3D {
|
|
id: particleSpark2
|
|
sprite: Texture {
|
|
source: "images/star3.png"
|
|
}
|
|
maxAmount: 30
|
|
fadeInDuration: 1000
|
|
fadeOutDuration: 1000
|
|
color: "#20ffffff"
|
|
colorVariation: Qt.vector4d(0.2, 0.2, 0.5, 0.1)
|
|
blendMode: SpriteParticle3D.Screen
|
|
}
|
|
ParticleEmitter3D {
|
|
y: 40 + mainWindow.separation * 60
|
|
particle: particleSpark2
|
|
scale: Qt.vector3d(3.8, 0, 3.8)
|
|
shape: ParticleShape3D {
|
|
type: ParticleShape3D.Cylinder
|
|
}
|
|
emitRate: 10
|
|
lifeSpan: 3000
|
|
particleScale: 4.0
|
|
particleScaleVariation: 3.0
|
|
particleRotationVariation: Qt.vector3d(20, 20, 180)
|
|
particleRotationVelocityVariation: Qt.vector3d(10, 10, 50)
|
|
}
|
|
Wander3D {
|
|
uniqueAmount: Qt.vector3d(10, 0, 10)
|
|
uniquePace: Qt.vector3d(0.1, 0.1, 0.1)
|
|
fadeInDuration: 2000
|
|
}
|
|
PointRotator3D {
|
|
particles: [ particleSpark2 ]
|
|
magnitude: -20
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsView {
|
|
CustomCheckBox {
|
|
id: checkBoxAnimateSpeed
|
|
text: "Animate Speed"
|
|
checked: true
|
|
}
|
|
CustomLabel {
|
|
text: "Speed"
|
|
opacity: !checkBoxAnimateSpeed.checked ? 1.0 : 0.4
|
|
}
|
|
CustomSlider {
|
|
id: sliderSpeedValue
|
|
sliderValue: gaugeItem.value
|
|
sliderEnabled: !checkBoxAnimateSpeed.checked
|
|
fromValue: 0
|
|
toValue: 1
|
|
onSliderValueChanged: gaugeItem.value = sliderValue;
|
|
}
|
|
CustomCheckBox {
|
|
id: checkBoxParticlesNeedle
|
|
text: "Particles Needle"
|
|
checked: true
|
|
}
|
|
CustomLabel {
|
|
text: "Needle emitRate"
|
|
opacity: checkBoxParticlesNeedle.checked ? 1.0 : 0.4
|
|
}
|
|
CustomSlider {
|
|
id: sliderNeedleEmitrate
|
|
sliderValue: 200
|
|
sliderEnabled: checkBoxParticlesNeedle.checked
|
|
fromValue: 50
|
|
toValue: 500
|
|
}
|
|
CustomLabel {
|
|
text: "Needle Brightness"
|
|
}
|
|
CustomSlider {
|
|
id: sliderNeedleBrightness
|
|
sliderValue: 10
|
|
fromValue: 0
|
|
toValue: 50
|
|
}
|
|
CustomLabel {
|
|
text: "Elements Separation"
|
|
}
|
|
CustomSlider {
|
|
id: sliderElementSeparation
|
|
sliderValue: 0
|
|
fromValue: 0
|
|
toValue: 1
|
|
}
|
|
}
|
|
|
|
LoggingView {
|
|
anchors.bottom: parent.bottom
|
|
particleSystems: [psystemGauge, psystemNeedle]
|
|
}
|
|
}
|