Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QML: Add scrolling waveforms #3967

Merged
merged 16 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2605,6 +2605,7 @@ set(
set(QT_EXTRA_COMPONENTS "")
if(QT6)
find_package(QT 6.2 NAMES Qt6 COMPONENTS Core REQUIRED)
list(APPEND QT_EXTRA_COMPONENTS "ShaderTools")
list(APPEND QT_EXTRA_COMPONENTS "SvgWidgets")
list(APPEND QT_EXTRA_COMPONENTS "Core5Compat")
list(APPEND QT_EXTRA_COMPONENTS "Quick")
Expand All @@ -2630,6 +2631,8 @@ if(QT_EXTRA_COMPONENTS)
endif()

if(QML)
add_subdirectory(res/shaders)

set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml)
qt_add_library(mixxx-qml-lib STATIC)
foreach(COMPONENT ${QT_COMPONENTS})
Expand Down Expand Up @@ -2689,6 +2692,8 @@ if(QML)
src/qml/asyncimageprovider.cpp
src/qml/qmlapplication.cpp
src/qml/qmlautoreload.cpp
src/qml/qmlbeatsmodel.cpp
src/qml/qmlcuesmodel.cpp
src/qml/qmlcontrolproxy.cpp
src/qml/qmlconfigproxy.cpp
src/qml/qmldlgpreferencesproxy.cpp
Expand Down
9 changes: 9 additions & 0 deletions res/qml/Theme/Theme.qml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ QtObject {
property color buttonNormalColor: midGray
property color textColor: lightGray2
property color toolbarActiveColor: white
property color waveformPrerollColor: midGray
property color waveformPostrollColor: midGray
property color waveformBeatColor: lightGray
property color waveformCursorColor: white
property color waveformMarkerDefault: '#ff7a01'
property color waveformMarkerLabel: Qt.rgba(255, 255, 255, 0.8)
property color waveformMarkerIntroOutroColor: '#2c5c9a'
property color waveformMarkerLoopColor: '#00b400'
property color waveformMarkerLoopColorDisabled: '#FFFFFF'
property string fontFamily: "Open Sans"
property int textFontPixelSize: 14
property int buttonFontPixelSize: 10
Expand Down
71 changes: 71 additions & 0 deletions res/qml/WaveformCue.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import Mixxx 1.0 as Mixxx
import QtQuick 2.15
import QtQuick.Shapes 1.4
import QtQuick.Window 2.15

import QtQuick.Controls 2.15

import "Theme"

Item {
id: root

property color color: Theme.waveformMarkerDefault

property real markerHeight: root.height
property color labelColor: Theme.waveformMarkerLabel
property real radiusSize: 4
property string cueLabel: qsTr("CUE")

FontMetrics {
id: fontMetrics
font.family: Theme.fontFamily
}

property rect contentRect: fontMetrics.tightBoundingRect(cueLabel)

Shape {
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: color
strokeStyle: ShapePath.SolidLine
startX: -1; startY: 0

PathLine { x: 8; y: 0 }
PathLine { x: 8 - radiusSize + contentRect.width; y: 0 }
PathArc {
x: 8 + contentRect.width
y: radiusSize
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: 8 + contentRect.width; y: 16 - radiusSize }
PathArc {
x: 8 - radiusSize + contentRect.width
y: 16
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: 8; y: 16 }
PathLine { x: 2; y: 16 }
PathLine { x: 2; y: markerHeight }
PathLine { x: -1; y: markerHeight }
PathLine { x: -1; y: 0 }
}
}
Shape {
ShapePath {
fillColor: labelColor
strokeColor: labelColor
PathText {
x: 3
y: 3
font.family: Theme.fontFamily
font.pixelSize: 13
font.weight: Font.Bold
text: cueLabel
}
}
}
}
100 changes: 100 additions & 0 deletions res/qml/WaveformHotcue.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import "." as Skin
import Mixxx 1.0 as Mixxx
import QtQuick 2.15
import QtQuick.Shapes 1.4
import QtQuick.Window 2.15

import QtQuick.Controls 2.15

import "Theme"

Item {
id: root

required property int hotcueNumber
required property string group
required property string label
property bool isLoop: false

Skin.Hotcue {
id: hotcue

group: root.group
hotcueNumber: root.hotcueNumber
}

property real markerHeight: root.height
property color labelColor: Theme.waveformMarkerLabel
property real radiusSize: 4
property string hotcueLabel: label != "" ? `${hotcueNumber}: ${label}` : `${hotcueNumber}`

FontMetrics {
id: fontMetrics
font.family: Theme.fontFamily
}

property rect contentRect: fontMetrics.tightBoundingRect(hotcueLabel)

Rectangle {
visible: root.isLoop
anchors.fill: parent
color: Qt.alpha(hotcue.color, 0.3)
}

Shape {
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: hotcue.color
strokeStyle: ShapePath.SolidLine
startX: -1; startY: 0

PathLine { x: 1; y: 0 }
PathLine { x: 1; y: markerHeight - 16 }
PathLine { x: 8 - radiusSize + contentRect.width; y: markerHeight - 16 }
PathArc {
x: 8 + contentRect.width
y: markerHeight - 16 + radiusSize
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: 8 + contentRect.width; y: markerHeight - radiusSize }
PathArc {
x: 8 - radiusSize + contentRect.width
y: markerHeight
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: -1; y: markerHeight }
PathLine { x: -1; y: 0 }
}
}
Shape {
visible: root.isLoop
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: hotcue.color
strokeStyle: ShapePath.SolidLine
startX: root.width - 1; startY: 0

PathLine { x: root.width - 1; y: markerHeight }
PathLine { x: root.width + 1; y: markerHeight }
PathLine { x: root.width + 1; y: 0 }
}
}
Shape {
ShapePath {
fillColor: labelColor
strokeColor: labelColor
PathText {
x: 3
y: markerHeight - 13
font.family: Theme.fontFamily
font.pixelSize: 13
font.weight: Font.Medium
text: hotcueLabel
}
}
}
}
95 changes: 95 additions & 0 deletions res/qml/WaveformIntroOutro.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import Mixxx 1.0 as Mixxx
import QtQuick 2.15
import QtQuick.Shapes 1.4
import QtQuick.Window 2.15

import QtQuick.Controls 2.15

import "Theme"

Item {
id: root

property color mainColor: Theme.waveformMarkerIntroOutroColor
property bool isIntro: true

property real markerHeight: root.height
property real radiusSize: 4

Rectangle {
anchors.fill: parent
color: Qt.alpha(root.mainColor, 0.1)
}

Shape {
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: root.mainColor
strokeStyle: ShapePath.SolidLine
startX: -1; startY: 0

PathLine { x: 16 - radiusSize; y: 0 }
PathArc {
x: 16
y: radiusSize
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: 16; y: 16 - radiusSize }
PathArc {
x: 16 - radiusSize
y: 16
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Clockwise
}
PathLine { x: 1; y: 16 }
PathLine { x: 1; y: markerHeight }
PathLine { x: -1; y: markerHeight }
}
}
Shape {
visible: root.width != 0
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: root.mainColor
strokeStyle: ShapePath.SolidLine
startX: root.width - 1; startY: 0

PathLine { x: root.width - 16 + radiusSize; y: 0 }
PathArc {
x: root.width - 16
y: radiusSize
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Counterclockwise
}
PathLine { x: root.width - 16; y: 16 - radiusSize }
PathArc {
x: root.width - 16 + radiusSize
y: 16
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Counterclockwise
}
PathLine { x: root.width -1; y: 16 }
PathLine { x: root.width -1; y: markerHeight }
PathLine { x: root.width + 1; y: markerHeight }
PathLine { x: root.width + 1; y: 0 }
}
}
Image {
x: 2
y: 2
width: 12
height: 12
source: `images/mark_${(root.isIntro ? 'intro' : 'outro')}.svg`
}
Image {
visible: root.width != 0
x: root.width - 14
y: 2
width: 12
height: 12
source: `images/mark_${(root.isIntro ? 'intro' : 'outro')}.svg`
}
}
76 changes: 76 additions & 0 deletions res/qml/WaveformLoop.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Mixxx 1.0 as Mixxx
import QtQuick 2.15
import QtQuick.Shapes 1.4
import QtQuick.Window 2.15

import QtQuick.Controls 2.15

import "Theme"

Item {
id: root

property color mainColor: Theme.waveformMarkerLoopColor
property color disabledColor: Theme.waveformMarkerLoopColorDisabled
property real enabledOpacity: 0.8
property real disabledOpacity: 0.5

property real markerHeight: root.height
property real radiusSize: 4
property bool enabled: true

Rectangle {
anchors.fill: parent
color: Qt.alpha(root.enabled ? root.mainColor : root.disabledColor, root.enabled ? root.enabledOpacity : root.disabledOpacity)
}

Shape {
ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: root.mainColor
strokeStyle: ShapePath.SolidLine
startX: -1; startY: 0

PathLine { x: -16 + radiusSize; y: 0 }
PathArc {
x: -16
y: radiusSize
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Counterclockwise
}
PathLine { x: -16; y: 16 - radiusSize }
PathArc {
x: -16 + radiusSize
y: 16
radiusX: radiusSize; radiusY: radiusSize
direction: PathArc.Counterclockwise
}
PathLine { x: -1; y: 16 }
PathLine { x: -1; y: markerHeight }
PathLine { x: 1; y: markerHeight }
PathLine { x: 1; y: 0 }
}
}
Shape {

ShapePath {
strokeWidth: 0
strokeColor: 'transparent'
fillColor: root.mainColor
strokeStyle: ShapePath.SolidLine
startX: root.width - 1; startY: 0

PathLine { x: root.width - 1; y: markerHeight }
PathLine { x: root.width + 1; y: markerHeight }
PathLine { x: root.width + 1; y: 0 }
}
}
Image {
x: -14
y: 2
width: 12
height: 12
source: "images/mark_loop.svg"
}
}