172 lines
6.6 KiB
QML
172 lines
6.6 KiB
QML
import QtQuick
|
|
import QtQuick3D
|
|
|
|
|
|
Node {
|
|
id: breezyDesktop
|
|
|
|
property var viewportResolution: effect.displayResolution
|
|
property var screens: root.screens
|
|
property var fovDetails: root.fovDetails
|
|
property var monitorPlacements: root.monitorPlacements
|
|
property int focusedMonitorIndex: -1
|
|
|
|
Displays {
|
|
id: displays
|
|
}
|
|
|
|
function displayAtIndex(index) {
|
|
if (index < 0 || index >= screens.length) {
|
|
return null;
|
|
}
|
|
return breezyDesktopDisplays.objectAt(index);
|
|
}
|
|
|
|
Repeater3D {
|
|
id: breezyDesktopDisplays
|
|
model: breezyDesktop.screens.length
|
|
delegate: BreezyDesktopDisplay {
|
|
screen: breezyDesktop.screens[index]
|
|
monitorPlacement: breezyDesktop.monitorPlacements[index]
|
|
|
|
property real monitorDistance: effect.allDisplaysDistance
|
|
property real targetDistance: effect.allDisplaysDistance
|
|
property real screenRotationY: displays.radianToDegree(monitorPlacement.rotationAngleRadians.y)
|
|
property real screenRotationX: displays.radianToDegree(monitorPlacement.rotationAngleRadians.x)
|
|
property matrix4x4 rotationMatrix: {
|
|
const matrix = Qt.matrix4x4();
|
|
matrix.rotate(screenRotationY, Qt.vector3d(0, 1, 0));
|
|
matrix.rotate(screenRotationX, Qt.vector3d(1, 0, 0));
|
|
return matrix;
|
|
}
|
|
|
|
property vector3d screenScale: {
|
|
const geometry = screen.geometry;
|
|
|
|
// apparently the default model unit size is 100x100, so we scale it up to the screen size
|
|
return Qt.vector3d(geometry.width / 100, geometry.height / 100, 1);
|
|
}
|
|
|
|
scale: screenScale
|
|
eulerRotation.y: screenRotationY
|
|
eulerRotation.x: screenRotationX
|
|
position: {
|
|
const displayNwu =
|
|
monitorPlacement.centerNoRotate
|
|
.times(monitorDistance / effect.allDisplaysDistance);
|
|
|
|
|
|
return rotationMatrix.times(displays.nwuToEusVector(displayNwu));
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: 500 // 500ms - 2x per second to avoid running this check too frequently
|
|
repeat: true
|
|
running: true
|
|
onTriggered: {
|
|
if (effect.imuRotations && effect.imuRotations.length > 0) {
|
|
let focusedIndex = -1;
|
|
|
|
if (effect.zoomOnFocusEnabled) {
|
|
focusedIndex = displays.findFocusedMonitor(
|
|
displays.eusToNwuQuat(effect.imuRotations[0]),
|
|
breezyDesktop.monitorPlacements.map(monitorVectors => monitorVectors.centerLook),
|
|
breezyDesktop.focusedMonitorIndex,
|
|
false, // TODO smooth follow
|
|
breezyDesktop.fovDetails,
|
|
breezyDesktop.screens.map(screen => screen.geometry)
|
|
);
|
|
}
|
|
|
|
if (focusedIndex !== breezyDesktop.focusedMonitorIndex) {
|
|
const unfocusedIndex = breezyDesktop.focusedMonitorIndex;
|
|
const focusedDisplay = focusedIndex !== -1 ? breezyDesktop.displayAtIndex(focusedIndex) : null;
|
|
const allDisplaysDistanceBinding = Qt.binding(function() { return effect.allDisplaysDistance; });
|
|
const focusedDisplayDistanceBinding = Qt.binding(function() { return effect.focusedDisplayDistance; });
|
|
if (focusedDisplay === null) {
|
|
const unfocusedDisplay = breezyDesktop.displayAtIndex(unfocusedIndex);
|
|
zoomOutAnimation.target = unfocusedDisplay;
|
|
zoomOutAnimation.target.targetDistance = effect.allDisplaysDistance;
|
|
zoomOutAnimation.start();
|
|
} else {
|
|
if (unfocusedIndex === -1) {
|
|
zoomInAnimation.target = focusedDisplay;
|
|
focusedDisplay.targetDistance = effect.focusedDisplayDistance;
|
|
zoomInAnimation.start();
|
|
} else {
|
|
zoomInSeqAnimation.target = focusedDisplay;
|
|
focusedDisplay.targetDistance = effect.focusedDisplayDistance;
|
|
|
|
const unfocusedDisplay = breezyDesktop.displayAtIndex(unfocusedIndex);
|
|
zoomOutSeqAnimation.target = unfocusedDisplay;
|
|
zoomOutSeqAnimation.target.targetDistance = effect.allDisplaysDistance;
|
|
|
|
zoomOnFocusSequence.start();
|
|
}
|
|
}
|
|
breezyDesktop.focusedMonitorIndex = focusedIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NumberAnimation {
|
|
id: zoomOutAnimation
|
|
property: "monitorDistance"
|
|
to: effect.allDisplaysDistance
|
|
duration: 150
|
|
running: false
|
|
onFinished: {
|
|
const unfocusedDisplay = zoomOutAnimation.target;
|
|
if (unfocusedDisplay) {
|
|
unfocusedDisplay.monitorDistance = Qt.binding(function() { return effect.allDisplaysDistance; });
|
|
}
|
|
}
|
|
}
|
|
|
|
NumberAnimation {
|
|
id: zoomInAnimation
|
|
property: "monitorDistance"
|
|
to: effect.focusedDisplayDistance
|
|
duration: 300
|
|
running: false
|
|
onFinished: {
|
|
const focusedDisplay = zoomInAnimation.target;
|
|
if (focusedDisplay) {
|
|
focusedDisplay.monitorDistance = Qt.binding(function() { return effect.focusedDisplayDistance; });
|
|
}
|
|
}
|
|
}
|
|
|
|
SequentialAnimation {
|
|
id: zoomOnFocusSequence
|
|
running: false
|
|
onFinished: {
|
|
const focusedDisplay = zoomInSeqAnimation.target;
|
|
if (focusedDisplay) {
|
|
focusedDisplay.monitorDistance = Qt.binding(function() { return effect.focusedDisplayDistance; });
|
|
}
|
|
const unfocusedDisplay = zoomOutSeqAnimation.target;
|
|
if (unfocusedDisplay) {
|
|
unfocusedDisplay.monitorDistance = Qt.binding(function() { return effect.allDisplaysDistance; });
|
|
}
|
|
}
|
|
|
|
NumberAnimation {
|
|
id: zoomOutSeqAnimation
|
|
property: "monitorDistance"
|
|
to: effect.allDisplaysDistance
|
|
duration: 150
|
|
}
|
|
PauseAnimation { duration: 50 }
|
|
NumberAnimation {
|
|
id: zoomInSeqAnimation
|
|
property: "monitorDistance"
|
|
to: effect.focusedDisplayDistance
|
|
duration: 300
|
|
}
|
|
}
|
|
}
|