diff --git a/res/skins/QMLDemo/Button.qml b/res/skins/QMLDemo/Button.qml new file mode 100644 index 00000000000..f667a118512 --- /dev/null +++ b/res/skins/QMLDemo/Button.qml @@ -0,0 +1,128 @@ +import "." as Skin +import QtGraphicalEffects 1.12 +import QtQml 2.12 +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +AbstractButton { + id: root + + property color normalColor: Theme.buttonNormalColor + property color activeColor // required + property color pressedColor: activeColor + property bool highlight: false + + implicitWidth: 52 + implicitHeight: 26 + states: [ + State { + name: "pressed" + when: root.pressed + + PropertyChanges { + target: backgroundImage + source: "images/button_pressed.svg" + } + + PropertyChanges { + target: label + color: root.pressedColor + } + + PropertyChanges { + target: labelGlow + visible: true + } + + }, + State { + name: "active" + when: (root.highlight || root.checked) && !root.pressed + + PropertyChanges { + target: backgroundImage + source: "images/button.svg" + } + + PropertyChanges { + target: label + color: root.activeColor + } + + PropertyChanges { + target: labelGlow + visible: true + } + + }, + State { + name: "inactive" + when: !root.checked && !root.highlight && !root.pressed + + PropertyChanges { + target: backgroundImage + source: "images/button.svg" + } + + PropertyChanges { + target: label + color: root.normalColor + } + + PropertyChanges { + target: labelGlow + visible: false + } + + } + ] + + background: BorderImage { + id: backgroundImage + + anchors.fill: parent + horizontalTileMode: BorderImage.Stretch + verticalTileMode: BorderImage.Stretch + source: "images/button.svg" + + border { + top: 10 + left: 10 + right: 10 + bottom: 10 + } + + } + + contentItem: Item { + anchors.fill: parent + + Glow { + id: labelGlow + + anchors.fill: parent + radius: 5 + spread: 0.1 + samples: 1 + radius * 2 + color: label.color + source: label + } + + Label { + id: label + + anchors.fill: parent + text: root.text + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: Theme.fontFamily + font.capitalization: Font.AllUppercase + font.bold: true + font.pixelSize: Theme.buttonFontPixelSize + color: root.normalColor + } + + } + +} diff --git a/res/skins/QMLDemo/ControlButton.qml b/res/skins/QMLDemo/ControlButton.qml new file mode 100644 index 00000000000..eb7a15ddf6a --- /dev/null +++ b/res/skins/QMLDemo/ControlButton.qml @@ -0,0 +1,16 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx + +Skin.Button { + id: root + + property string group // required + property string key // required + + Mixxx.ControlProxy { + group: root.group + key: root.key + value: root.checked || root.down + } + +} diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml new file mode 100644 index 00000000000..559f187cd52 --- /dev/null +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -0,0 +1,49 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +Item { + id: root + + property real crossfaderWidth // required + + implicitHeight: crossfaderSlider.width + + Item { + id: effectUnitLeftPlaceholder + + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: parent.bottom + } + + Skin.Slider { + id: crossfaderSlider + + anchors.centerIn: parent + height: root.crossfaderWidth + group: "[Master]" + key: "crossfader" + barColor: Theme.crossfaderBarColor + barStart: 0.5 + fg: "images/slider_handle_crossfader.svg" + bg: "images/slider_crossfader.svg" + + transform: Rotation { + origin.x: crossfaderSlider.width / 2 + origin.y: crossfaderSlider.height / 2 + angle: 90 + } + + } + + Item { + id: effectUnitRightPlaceholder + + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + } + +} diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index 2cbe3c6544f..58a86a615f8 100644 --- a/res/skins/QMLDemo/Deck.qml +++ b/res/skins/QMLDemo/Deck.qml @@ -1,400 +1,357 @@ +import "." as Skin import Mixxx 0.1 as Mixxx import Mixxx.Controls 0.1 as MixxxControls import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.11 +import "Theme" Item { id: root - required property string group + property string group // required - ColumnLayout { - anchors.fill: parent + Skin.DeckInfoBar { + id: infoBar - RowLayout { - Layout.fillWidth: true - Layout.fillHeight: true - - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - - Rectangle { - id: trackInfo - - Layout.fillWidth: true - height: 60 - color: "#121213" - - Rectangle { - id: coverArt - - anchors.top: parent.top - anchors.left: parent.left - anchors.bottom: parent.bottom - width: height - color: "black" - } - - Item { - id: spinny - - anchors.fill: coverArt - - // The Spinnies are automatically hidden if the track - // is stopped. This is not really useful, but is nice for - // demo'ing transitions. - Mixxx.ControlProxy { - group: root.group - key: "play" - onValueChanged: spinnyIndicator.indicatorVisible = (value > 0) - } - - MixxxControls.Spinny { - id: spinnyIndicator - - anchors.fill: parent - group: root.group - indicatorVisible: false - - indicatorDelegate: Image { - mipmap: true - width: spinnyIndicator.width - height: spinnyIndicator.height - source: "../LateNight/palemoon/style/spinny_indicator.svg" - } - - } - - } - - Item { - id: trackText - - anchors.top: parent.top - anchors.left: coverArt.right - anchors.right: parent.right - anchors.bottom: parent.bottom - - ColumnLayout { - anchors.fill: parent - anchors.margins: 5 - - Text { - id: trackTitle - - Layout.fillWidth: true - Layout.fillHeight: true - text: "Title Placeholder" - elide: Text.ElideRight - color: "#c2b3a5" - } - - Rectangle { - id: trackColor - - Layout.fillWidth: true - implicitHeight: 3 - color: "black" - } - - Text { - id: trackArtist + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + color: Theme.deckBackgroundColor + group: root.group + } - Layout.fillWidth: true - Layout.fillHeight: true - text: "Artist Placeholder" - elide: Text.ElideRight - color: "#c2b3a5" - } + Skin.Slider { + id: rateSlider + + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.top: infoBar.bottom + anchors.right: parent.right + anchors.bottom: buttonBar.top + width: syncButton.width + group: root.group + key: "rate" + barStart: 0.5 + barColor: Theme.bpmSliderBarColor + bg: "images/slider_bpm.svg" + } - } + Rectangle { + id: overview + + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.rightMargin: 5 + anchors.top: infoBar.bottom + anchors.bottom: buttonBar.top + anchors.left: parent.left + anchors.right: rateSlider.left + radius: 5 + color: Theme.deckBackgroundColor + height: 56 + + Skin.WaveformOverview { + group: root.group + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: parent.height - 26 + } - } + Item { + id: waveformBar - } + height: 26 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + Rectangle { + id: waveformBarVSeparator + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.leftMargin: 5 + height: 2 + color: infoBar.lineColor + } - WaveformOverview { - Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter - Layout.fillWidth: true - Layout.fillHeight: true - group: root.group + InfoBarButton { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 5 + width: rateSlider.width + group: "[EffectRack1_EffectUnit1]" + key: "group_" + root.group + "_enable" + checkable: true + activeColor: Theme.deckActiveColor + + foreground: Text { + anchors.centerIn: parent + text: "FX 1" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.bold: true + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor } } - Item { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.fillHeight: true - implicitWidth: 50 - - MixxxControls.ToggleButton { - id: syncButton + Rectangle { + id: waveformBarHSeparator1 - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: 24 - group: root.group - key: "sync_enabled" - icon.width: 50 - icon.height: 24 - - State { - name: "0" - - PropertyChanges { - target: syncButton - icon.source: "../LateNight/palemoon/buttons/btn__sync_deck.svg" - icon.color: "#777777" - background.color: "transparent" - background.border.width: 2 - } - - PropertyChanges { - target: syncButtonBgImage - source: "../LateNight/palemoon/buttons/btn_embedded_sync.svg" - } - - } - - State { - name: "1" - - PropertyChanges { - target: syncButton - icon.source: "../LateNight/palemoon/buttons/btn__sync_deck_active.svg" - icon.color: "transparent" - background.color: "#b24c12" - background.border.width: 2 - } - - PropertyChanges { - target: syncButtonBgImage - source: "../LateNight/palemoon/buttons/btn_embedded_sync_active.svg" - } - - } + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: waveformBarVSeparator.left + anchors.leftMargin: rateSlider.width + width: 2 + color: infoBar.lineColor + } - background: Rectangle { - anchors.fill: parent + InfoBarButton { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: waveformBarHSeparator1.left + width: rateSlider.width + group: "[EffectRack1_EffectUnit2]" + key: "group_" + root.group + "_enable" + checkable: true + activeColor: Theme.deckActiveColor + + foreground: Text { + anchors.centerIn: parent + text: "FX 2" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.bold: true + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + } - data: Image { - id: syncButtonBgImage + } - anchors.fill: parent - } + Rectangle { + id: waveformBarHSeparator2 - } + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: waveformBarHSeparator1.right + anchors.leftMargin: rateSlider.width + width: 2 + color: infoBar.lineColor + } + Text { + id: waveformBarPosition + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: waveformBarHSeparator2.right + anchors.leftMargin: 5 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + text: { + const positionSeconds = samplesControl.value / 2 / sampleRateControl.value * playPositionControl.value; + if (isNaN(positionSeconds)) + return ""; + + let minutes = Math.floor(positionSeconds / 60); + let seconds = positionSeconds - (minutes * 60); + let centiseconds = Math.trunc((seconds - Math.trunc(seconds)) * 100); + seconds = Math.trunc(seconds); + if (minutes < 10) + minutes = "0" + minutes; + + if (seconds < 10) + seconds = "0" + seconds; + + if (centiseconds < 10) + centiseconds = "0" + centiseconds; + + return minutes + ':' + seconds + "." + centiseconds; } Mixxx.ControlProxy { - id: bpmControl + id: playPositionControl group: root.group - key: "bpm" - } - - Text { - id: bpmText - - anchors.top: syncButton.bottom - anchors.left: parent.left - anchors.right: parent.right - height: contentHeight - text: bpmControl.value.toFixed(2) - horizontalAlignment: Text.AlignHCenter - font.family: "Open Sans" - font.bold: true - font.pixelSize: 11 - color: "#777" + key: "playposition" } Mixxx.ControlProxy { - id: rateRatioControl + id: sampleRateControl group: root.group - key: "rate_ratio" + key: "track_samplerate" } - Text { - id: bpmRatioText - - property real ratio: ((rateRatioControl.value - 1) * 100).toPrecision(2) - - anchors.top: bpmText.bottom - anchors.left: parent.left - anchors.right: parent.right - height: contentHeight - text: (ratio > 0) ? "+" + ratio.toFixed(2) : ratio.toFixed(2) - horizontalAlignment: Text.AlignHCenter - font.family: "Open Sans" - font.bold: true - font.pixelSize: 10 - color: "#404040" - } - - MixxxControls.Slider { - id: rateSlider + Mixxx.ControlProxy { + id: samplesControl - anchors.top: bpmRatioText.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom group: root.group - key: "rate" - bar: true - barColor: "#257b82" - barMargin: 10 - barStart: 0.5 - - handle: Image { - source: "../LateNight/palemoon/sliders/knob_volume_deck.svg" - width: 42 - height: 19 - } - - background: Image { - anchors.fill: parent - source: "../LateNight/palemoon/sliders/slider_volume_deck.svg" - } - + key: "track_samples" } } - } - - Rectangle { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.fillWidth: true - height: 26 - color: "transparent" + Item { + id: waveformBarRightSpace - RowLayout { - anchors.fill: parent + anchors.top: waveformBar.top + anchors.bottom: waveformBar.bottom + anchors.right: waveformBar.right + width: rateSlider.width + } - Rectangle { - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - implicitWidth: 68 - implicitHeight: 26 - color: "#121213" + Rectangle { + id: waveformBarHSeparator - MixxxControls.ToggleButton { - id: playButton + anchors.top: waveformBar.top + anchors.bottom: waveformBar.bottom + anchors.right: waveformBarRightSpace.left + anchors.bottomMargin: 5 + width: 2 + color: infoBar.lineColor + } - anchors.fill: parent - group: root.group - key: "play" - icon.width: 50 - icon.height: 24 + InfoBarButton { + anchors.top: waveformBarVSeparator.bottom + anchors.bottom: waveformBar.bottom + anchors.left: waveformBarRightSpace.left + anchors.right: waveformBarRightSpace.right + group: root.group + key: "quantize" + checkable: true + activeColor: Theme.deckActiveColor + + foreground: Image { + anchors.centerIn: parent + source: "images/icon_quantize.svg" + } - State { - name: "0" + } - PropertyChanges { - target: playButton - icon.source: "../LateNight/palemoon/buttons/btn__play_deck.svg" - icon.color: "#777777" - background.color: "transparent" - background.border.width: 2 - } + Item { + id: waveformBarLeftSpace - PropertyChanges { - target: playButtonBgImage - source: "../LateNight/palemoon/buttons/btn_embedded_play.svg" - } + anchors.top: waveformBar.top + anchors.bottom: waveformBar.bottom + anchors.right: waveformBarHSeparator.left + width: rateSlider.width + } - } + Rectangle { + id: waveformBarHSeparator3 - State { - name: "1" + anchors.top: waveformBar.top + anchors.bottom: waveformBar.bottom + anchors.right: waveformBarLeftSpace.left + anchors.bottomMargin: 5 + width: 2 + color: infoBar.lineColor + } - PropertyChanges { - target: playButton - icon.source: "../LateNight/palemoon/buttons/btn__play_deck_active.svg" - icon.color: "transparent" - background.color: "#b24c12" - background.border.width: 2 - } + InfoBarButton { + anchors.top: waveformBarVSeparator.bottom + anchors.bottom: waveformBar.bottom + anchors.left: waveformBarLeftSpace.left + anchors.right: waveformBarLeftSpace.right + group: root.group + key: "passthrough" + checkable: true + activeColor: Theme.deckActiveColor + + foreground: Image { + anchors.centerIn: parent + source: "images/icon_passthrough.svg" + } - PropertyChanges { - target: playButtonBgImage - source: "../LateNight/palemoon/buttons/btn_embedded_play_active.svg" - } + } - } + } - background: Rectangle { - anchors.fill: parent + } - data: Image { - id: playButtonBgImage + Item { + id: buttonBar - anchors.fill: parent - } + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 56 - } + Skin.ControlButton { + id: cueButton - } + anchors.left: parent.left + anchors.top: parent.top + group: root.group + key: "cue_default" + text: "Cue" + activeColor: Theme.deckActiveColor + } - } + Skin.ControlButton { + id: playButton + + anchors.top: cueButton.bottom + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.topMargin: 5 + group: root.group + key: "play" + text: "Play" + checkable: true + activeColor: Theme.deckActiveColor + } - Item { - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.fillWidth: true - Layout.fillHeight: true + Row { + anchors.left: cueButton.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.leftMargin: 10 + spacing: -1 + + Repeater { + model: 8 + + Skin.HotcueButton { + // TODO: Once we require Qt >= 5.14, we're going to re-add + // the `required` keyword. If the component has any + // required properties, we'll stumble over a Qt bug and + // need the following workaround: + // required property int index + // See this for details: + // https://bugreports.qt.io/browse/QTBUG-86009, and need + + hotcueNumber: index + 1 + group: root.group } - Item { - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - implicitWidth: 50 - implicitHeight: 20 - - Mixxx.ControlProxy { - id: passthroughControl - - group: root.group - key: "passthrough" - } - - Switch { - id: passthroughSwitch - - width: parent.implicitWidth - height: 18 - anchors.margins: 5 - text: "Passthrough" - checked: passthroughControl.value - onCheckedChanged: passthroughControl.value = checked - - indicator: Rectangle { - anchors.fill: parent - x: passthroughSwitch.leftPadding - y: parent.height / 2 - height / 2 - radius: height / 2 - color: passthroughSwitch.checked ? "#202020" : "#121213" - border.color: "#404040" - - Rectangle { - x: passthroughSwitch.checked ? parent.width - width : 0 - height: passthroughSwitch.height - width: height - radius: height / 2 - color: passthroughSwitch.checked ? "#777" : "#404040" - border.color: "#404040" - } - - } - - } + } - } + } - } + Skin.ControlButton { + id: syncButton + anchors.right: parent.right + anchors.top: parent.top + text: "Sync" + group: root.group + key: "sync_enabled" + checkable: true + activeColor: Theme.deckActiveColor } } diff --git a/res/skins/QMLDemo/DeckInfoBar.qml b/res/skins/QMLDemo/DeckInfoBar.qml new file mode 100644 index 00000000000..ee897b247ef --- /dev/null +++ b/res/skins/QMLDemo/DeckInfoBar.qml @@ -0,0 +1,200 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import Mixxx.Controls 0.1 as MixxxControls +import QtQuick 2.12 +import "Theme" + +Rectangle { + id: root + + property string group // required + property color textColor: Theme.deckTextColor + property color lineColor: Theme.deckLineColor + + radius: 5 + height: 56 + + Rectangle { + id: coverArt + + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 5 + width: height + radius: height / 2 + border.width: 2 + border.color: Theme.deckLineColor + color: "transparent" + } + + Item { + id: spinny + + anchors.fill: coverArt + + // The Spinnies are automatically hidden if the track + // is stopped. This is not really useful, but is nice for + // demo'ing transitions. + Mixxx.ControlProxy { + group: root.group + key: "play" + onValueChanged: spinnyIndicator.indicatorVisible = (value > 0) + } + + MixxxControls.Spinny { + id: spinnyIndicator + + anchors.fill: parent + group: root.group + indicatorVisible: false + + indicator: Item { + width: spinnyIndicator.width + height: spinnyIndicator.height + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: 2 + height: parent.height / 2 + color: Theme.deckTextColor + } + + } + + } + + } + + Text { + id: infoBarTitle + + text: "Title Placeholder" + anchors.top: infoBarHSeparator1.top + anchors.left: infoBarVSeparator.left + anchors.right: infoBarHSeparator1.left + anchors.bottom: infoBarVSeparator.bottom + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + } + + Rectangle { + id: infoBarVSeparator + + anchors.left: coverArt.right + anchors.right: infoBar.right + anchors.verticalCenter: infoBar.verticalCenter + anchors.margins: 5 + height: 2 + color: infoBar.lineColor + } + + Text { + id: infoBarArtist + + text: "Artist Placeholder" + anchors.top: infoBarVSeparator.bottom + anchors.left: infoBarVSeparator.left + anchors.right: infoBarHSeparator1.left + anchors.bottom: infoBarHSeparator1.bottom + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + } + + Rectangle { + id: infoBarHSeparator1 + + anchors.top: infoBar.top + anchors.bottom: infoBar.bottom + anchors.right: infoBarKey.left + anchors.topMargin: 5 + anchors.bottomMargin: 5 + width: 2 + color: infoBar.lineColor + } + + Text { + id: infoBarKey + + anchors.top: infoBarHSeparator1.top + anchors.bottom: infoBarVSeparator.top + width: rateSlider.width + anchors.right: infoBarHSeparator2.left + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: "KEY" + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + } + + Rectangle { + id: infoBarHSeparator2 + + anchors.top: infoBar.top + anchors.bottom: infoBar.bottom + anchors.right: infoBarRateRatio.left + anchors.topMargin: 5 + anchors.bottomMargin: 5 + width: 2 + color: infoBar.lineColor + } + + Text { + id: infoBarRate + + anchors.top: infoBarHSeparator2.top + anchors.bottom: infoBarVSeparator.top + width: rateSlider.width + anchors.right: infoBar.right + anchors.rightMargin: 5 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: bpmControl.value.toFixed(2) + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + + Mixxx.ControlProxy { + id: bpmControl + + group: root.group + key: "bpm" + } + + } + + Text { + id: infoBarRateRatio + + property real ratio: ((rateRatioControl.value - 1) * 100).toPrecision(2) + + anchors.top: infoBarVSeparator.bottom + anchors.bottom: infoBarHSeparator1.bottom + width: rateSlider.width + anchors.right: infoBar.right + anchors.rightMargin: 5 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: infoBar.textColor + text: (ratio > 0) ? "+" + ratio.toFixed(2) : ratio.toFixed(2) + + Mixxx.ControlProxy { + id: rateRatioControl + + group: root.group + key: "rate_ratio" + } + + } + +} diff --git a/res/skins/QMLDemo/DeckRow.qml b/res/skins/QMLDemo/DeckRow.qml index f6725626bd8..e33d8e7d30d 100644 --- a/res/skins/QMLDemo/DeckRow.qml +++ b/res/skins/QMLDemo/DeckRow.qml @@ -1,72 +1,44 @@ -import Mixxx 0.1 as Mixxx -import Mixxx.Controls 0.1 as MixxxControls import QtQuick 2.12 import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.11 Item { id: root - required property string leftDeck - required property string rightDeck + property string leftDeckGroup // required + property string rightDeckGroup // required + property alias mixer: mixer - RowLayout { - anchors.fill: parent - anchors.leftMargin: 10 - anchors.rightMargin: 10 - Layout.margins: 10 + implicitHeight: mixer.height - Deck { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.fillWidth: true - Layout.fillHeight: true - group: root.leftDeck - } + Deck { + id: leftDeck - Rectangle { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - implicitWidth: 200 - Layout.fillHeight: true - color: "#1e1e20" - border.color: "#121213" - border.width: 2 - radius: 1 - - RowLayout { - anchors.fill: parent - anchors.margins: 10 - - EqColumn { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - group: root.leftDeck - } - - MixerColumn { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - group: root.leftDeck - } - - MixerColumn { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - group: root.rightDeck - } - - EqColumn { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - group: root.rightDeck - } + anchors.top: parent.top + anchors.left: parent.left + anchors.right: mixer.left + anchors.bottom: parent.bottom + anchors.rightMargin: 5 + group: root.leftDeckGroup + } - } + Mixer { + id: mixer - } + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + leftDeckGroup: root.leftDeckGroup + rightDeckGroup: root.rightDeckGroup + } - Deck { - Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.fillWidth: true - Layout.fillHeight: true - group: root.rightDeck - } + Deck { + id: rightDeck + anchors.top: parent.top + anchors.left: mixer.right + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.leftMargin: 5 + group: root.rightDeckGroup } } diff --git a/res/skins/QMLDemo/EqColumn.qml b/res/skins/QMLDemo/EqColumn.qml index bf3af882c4a..cc82669640b 100644 --- a/res/skins/QMLDemo/EqColumn.qml +++ b/res/skins/QMLDemo/EqColumn.qml @@ -1,57 +1,51 @@ +import "." as Skin import Mixxx.Controls 0.1 as MixxxControls import QtQuick 2.12 -import QtQuick.Layouts 1.11 +import QtQuick.Shapes 1.12 +import "Theme" -Item { +Column { id: root - required property string group - - implicitWidth: 35 - implicitHeight: 150 - - ColumnLayout { - EqKnob { - channelGroup: root.group - key: "parameter3" - } - - EqKnob { - channelGroup: root.group - key: "parameter2" - } - - EqKnob { - channelGroup: root.group - key: "parameter1" - } - - MixxxControls.Knob { - id: filterKnob - - width: 35 - height: width - group: "[QuickEffectRack1_" + root.group + "]" - key: "super1" - arc: true - arcRadius: 15 - arcColor: "#518f00" - arcWidth: 2 - - background: Image { - source: "../LateNight/palemoon/knobs/knob_bg_master.svg" - width: filterKnob.width - height: filterKnob.width / 7 * 6 - } - - foreground: Image { - source: "../LateNight/palemoon/knobs/knob_indicator_regular_green.svg" - width: filterKnob.width - height: filterKnob.width / 7 * 6 - } - - } + property string group // required + spacing: 4 + + EqKnob { + group: "[EqualizerRack1_" + root.group + "_Effect1]" + key: "parameter3" + statusKey: "button_parameter3" + color: Theme.eqHighColor + } + + EqKnob { + group: "[EqualizerRack1_" + root.group + "_Effect1]" + key: "parameter2" + statusKey: "button_parameter2" + color: Theme.eqMidColor + } + + EqKnob { + group: "[EqualizerRack1_" + root.group + "_Effect1]" + key: "parameter1" + statusKey: "button_parameter1" + color: Theme.eqLowColor + } + + EqKnob { + group: "[QuickEffectRack1_" + root.group + "]" + key: "super1" + statusGroup: "[QuickEffectRack1_" + root.group + "_Effect1]" + statusKey: "enabled" + arcStyle: ShapePath.DashLine + arcStylePattern: [2, 2] + color: Theme.eqFxColor + } + + Skin.OrientationToggleButton { + group: root.group + key: "orientation" + color: Theme.crossfaderOrientationColor } } diff --git a/res/skins/QMLDemo/EqKnob.qml b/res/skins/QMLDemo/EqKnob.qml index d00d7de8ca6..171c65d9192 100644 --- a/res/skins/QMLDemo/EqKnob.qml +++ b/res/skins/QMLDemo/EqKnob.qml @@ -1,35 +1,39 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx import Mixxx.Controls 0.1 as MixxxControls import QtQuick 2.12 +import "Theme" -Item { +Skin.Knob { id: root - required property string channelGroup - property alias key: knob.key + property string statusGroup: root.group // required + property string statusKey // required - width: 35 - height: 35 + Mixxx.ControlProxy { + id: statusControl - MixxxControls.Knob { - id: knob - - anchors.fill: parent - group: "[EqualizerRack1_" + channelGroup + "_Effect1]" - arc: true - arcRadius: 15 - arcColor: "#858585" - arcWidth: 2 - - background: Image { - source: "../LateNight/palemoon/knobs/knob_bg_master.svg" - width: 35 - height: 30 - } + group: root.statusGroup + key: root.statusKey + } - foreground: Image { - source: "../LateNight/palemoon/knobs/knob_indicator_regular_red.svg" - width: 35 - height: 30 + Rectangle { + id: statusButton + + anchors.left: root.left + anchors.bottom: root.bottom + anchors.leftMargin: 6 + anchors.bottomMargin: 2 + width: 8 + height: width + radius: width / 2 + border.width: 1 + border.color: Theme.buttonNormalColor + color: statusControl.value ? root.color : "transparent" + + MouseArea { + anchors.fill: parent + onClicked: statusControl.value = !statusControl.value } } diff --git a/res/skins/QMLDemo/HiddenState.qml b/res/skins/QMLDemo/HiddenState.qml new file mode 100644 index 00000000000..19435a9b3e3 --- /dev/null +++ b/res/skins/QMLDemo/HiddenState.qml @@ -0,0 +1,15 @@ +import QtQuick 2.12 + +State { + property alias target: changes.target + + name: "hidden" + + PropertyChanges { + id: changes + + opacity: 0 + visible: false + } + +} diff --git a/res/skins/QMLDemo/HiddenTransition.qml b/res/skins/QMLDemo/HiddenTransition.qml new file mode 100644 index 00000000000..65379d70b53 --- /dev/null +++ b/res/skins/QMLDemo/HiddenTransition.qml @@ -0,0 +1,25 @@ +import QtQuick 2.12 + +Transition { + id: root + + property var target // required + + to: "hidden" + reversible: true + + SequentialAnimation { + NumberAnimation { + target: root.target + property: "opacity" + duration: 150 + } + + PropertyAction { + target: root.target + property: "visible" + } + + } + +} diff --git a/res/skins/QMLDemo/HotcueButton.qml b/res/skins/QMLDemo/HotcueButton.qml new file mode 100644 index 00000000000..c5aec57558e --- /dev/null +++ b/res/skins/QMLDemo/HotcueButton.qml @@ -0,0 +1,97 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +Skin.Button { + id: root + + property int hotcueNumber // required + property string group // required + + text: hotcueNumber + width: playButton.height + height: playButton.height + activeColor: { + if (hotcueColorControl.value < 0) + return Theme.deckActiveColor; + + return "#" + hotcueColorControl.value.toString(16).padStart(6, "0"); + } + highlight: hotcueControl.value + + Mixxx.ControlProxy { + id: hotcueColorControl + + group: root.group + key: "hotcue_" + hotcueNumber + "_color" + } + + Mixxx.ControlProxy { + group: root.group + key: "hotcue_" + hotcueNumber + "_activate" + value: root.down + } + + Mixxx.ControlProxy { + id: hotcueControl + + group: root.group + key: "hotcue_" + hotcueNumber + "_enabled" + } + + Mixxx.ControlProxy { + id: hotcueClearControl + + group: root.group + key: "hotcue_" + hotcueNumber + "_clear" + } + + MouseArea { + id: mousearea + + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: { + popup.x = mouse.x; + popup.y = mouse.y; + popup.open(); + } + } + + Popup { + id: popup + + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + + Text { + text: "Cue Popup Placeholder" + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: Theme.deckTextColor + anchors.centerIn: parent + } + + background: BorderImage { + id: backgroundImage + + anchors.fill: parent + horizontalTileMode: BorderImage.Stretch + verticalTileMode: BorderImage.Stretch + source: "images/button.svg" + + border { + top: 10 + left: 20 + right: 20 + bottom: 10 + } + + } + + } + +} diff --git a/res/skins/QMLDemo/InfoBarButton.qml b/res/skins/QMLDemo/InfoBarButton.qml new file mode 100644 index 00000000000..c252b57066f --- /dev/null +++ b/res/skins/QMLDemo/InfoBarButton.qml @@ -0,0 +1,71 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import QtGraphicalEffects 1.12 +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +AbstractButton { + id: root + + property string group // required + property string key // required + property alias foreground: foreground.data + property color normalColor: Theme.buttonNormalColor + property color activeColor // required + property color pressedColor: activeColor + + states: [ + State { + name: "pressed" + when: root.pressed + + PropertyChanges { + target: colorOverlay + color: root.pressedColor + } + + }, + State { + name: "active" + when: root.checked && !root.pressed + + PropertyChanges { + target: colorOverlay + color: root.activeColor + } + + }, + State { + name: "inactive" + when: !root.checked && !root.pressed + + PropertyChanges { + target: colorOverlay + color: root.normalColor + } + + } + ] + + Mixxx.ControlProxy { + group: root.group + key: root.key + value: root.checked || root.down + } + + Item { + id: foreground + + anchors.fill: parent + } + + ColorOverlay { + id: colorOverlay + + anchors.fill: foreground + source: foreground + color: root.normalColor + } + +} diff --git a/res/skins/QMLDemo/Knob.qml b/res/skins/QMLDemo/Knob.qml new file mode 100644 index 00000000000..5d8acdc0c96 --- /dev/null +++ b/res/skins/QMLDemo/Knob.qml @@ -0,0 +1,38 @@ +import Mixxx.Controls 0.1 as MixxxControls +import QtQuick 2.12 +import "Theme" + +MixxxControls.Knob { + id: root + + property color color // required + + implicitWidth: 56 + implicitHeight: implicitWidth + arc: true + arcRadius: 20 + arcColor: root.color + arcWidth: 2 + angle: 117 + + background: Image { + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + source: "images/knob.svg" + } + + foreground: Item { + anchors.fill: parent + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: root.width / 30 + height: root.width / 7 + y: parent.height / 4 + color: root.color + } + + } + +} diff --git a/res/skins/QMLDemo/Library.qml b/res/skins/QMLDemo/Library.qml index ee0ad35b48d..f8437c5813f 100644 --- a/res/skins/QMLDemo/Library.qml +++ b/res/skins/QMLDemo/Library.qml @@ -1,15 +1,19 @@ +import "." as Skin import Qt.labs.qmlmodels 1.0 import QtQuick 2.12 import QtQuick.Controls 1.4 +import "Theme" Item { Rectangle { - color: "#121213" + color: Theme.deckBackgroundColor anchors.fill: parent Text { text: "Library Placeholder" - color: "white" + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: Theme.deckTextColor anchors.centerIn: parent } diff --git a/res/skins/QMLDemo/Mixer.qml b/res/skins/QMLDemo/Mixer.qml new file mode 100644 index 00000000000..11ecd0390e0 --- /dev/null +++ b/res/skins/QMLDemo/Mixer.qml @@ -0,0 +1,33 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +Row { + id: mixer + + property string leftDeckGroup // required + property string rightDeckGroup // required + property bool show4decks: false + + EqColumn { + group: root.leftDeckGroup + } + + MixerColumn { + width: 56 + height: parent.height + group: root.leftDeckGroup + } + + MixerColumn { + width: 56 + height: parent.height + group: root.rightDeckGroup + } + + EqColumn { + width: 56 + height: parent.height + group: root.rightDeckGroup + } + +} diff --git a/res/skins/QMLDemo/MixerColumn.qml b/res/skins/QMLDemo/MixerColumn.qml index 94d18a13384..580bffc374f 100644 --- a/res/skins/QMLDemo/MixerColumn.qml +++ b/res/skins/QMLDemo/MixerColumn.qml @@ -1,69 +1,50 @@ -import Mixxx.Controls 0.1 as MixxxControls +import "." as Skin import QtQuick 2.12 import QtQuick.Layouts 1.11 +import "Theme" Item { id: root - required property string group + property string group // required - implicitWidth: 47 - implicitHeight: 150 + Knob { + id: gainKnob - ColumnLayout { - MixxxControls.Knob { - id: gainKnob - - Layout.alignment: Qt.AlignHCenter | Qt.AlignTop - width: 35 - height: width - group: root.group - key: "pregain" - arc: true - arcRadius: 15 - arcColor: "#b96300" - arcWidth: 2 - - background: Image { - source: "../LateNight/palemoon/knobs/knob_bg_master.svg" - width: gainKnob.width - height: gainKnob.width / 7 * 6 - } - - foreground: Image { - source: "../LateNight/palemoon/knobs/knob_indicator_regular_orange.svg" - width: gainKnob.width - height: gainKnob.width / 7 * 6 - } - - } - - MixxxControls.Slider { - id: volumeSlider - - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom - width: root.width - height: 107 - group: root.group - key: "volume" - bar: true - barColor: "#257b82" - barMargin: 10 - - handle: Image { - source: "../LateNight/palemoon/sliders/knob_volume_deck.svg" - width: 42 - height: 19 - } - - background: Image { - width: volumeSlider.width - height: volumeSlider.height - source: "../LateNight/palemoon/sliders/slider_volume_deck.svg" - } + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: width + group: root.group + key: "pregain" + color: Theme.gainKnobColor + } - } + Slider { + id: volumeSlider + + anchors.top: gainKnob.bottom + anchors.topMargin: 5 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: pflButton.top + group: root.group + key: "volume" + barColor: Theme.volumeSliderBarColor + bg: "images/slider_volume.svg" + } + Skin.ControlButton { + id: pflButton + + group: root.group + key: "pfl" + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + text: "PFL" + activeColor: Theme.pflActiveButtonColor + checkable: true } } diff --git a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml index 28bae664e85..c69bfb9f86f 100644 --- a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml +++ b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml @@ -32,22 +32,16 @@ Item { key: root.key + "_set_default" } - Rectangle { + Item { id: background - width: root.width - height: root.height - anchors.centerIn: root - color: "transparent" + anchors.fill: parent } - Rectangle { + Item { id: foreground - width: root.width - height: root.height - anchors.centerIn: root - color: "transparent" + anchors.fill: parent rotation: (control.parameter - (root.max - root.min) / 2) * 2 * root.angle } @@ -84,9 +78,9 @@ Item { anchors.fill: root onWheel: { if (wheel.angleDelta.y < 0) - control.parameter = control.parameter + 0.1; + control.parameter = Math.min(root.max, control.parameter + 0.1); else - control.parameter = control.parameter - 0.1; + control.parameter = Math.max(root.min, control.parameter - 0.1); } onDoubleClicked: resetcontrol.value = 1 onPressed: { @@ -94,8 +88,9 @@ Item { } onPositionChanged: { if (mousearea.pressed) { - var dy = mousearea.posy - mouse.y; - control.parameter += Math.max(Math.min(dy, 100), -100) / 100; + const dy = mousearea.posy - mouse.y; + let parameter = control.parameter + Math.max(Math.min(dy, 100), -100) / 100; + control.parameter = Math.max(root.min, Math.min(root.max, parameter)); mousearea.posy = mouse.y; } } diff --git a/res/skins/QMLDemo/Mixxx/Controls/Spinny.qml b/res/skins/QMLDemo/Mixxx/Controls/Spinny.qml index d95d0516a8d..07c8012cb7b 100644 --- a/res/skins/QMLDemo/Mixxx/Controls/Spinny.qml +++ b/res/skins/QMLDemo/Mixxx/Controls/Spinny.qml @@ -1,13 +1,14 @@ import Mixxx 0.1 as Mixxx import QtQuick 2.12 +import QtQuick.Controls 2.12 Item { id: root - required property string group + property string group // required property real rpm: 33 property bool indicatorVisible: true - property alias indicatorDelegate: indicatorContainer.data + property alias indicator: indicatorContainer.contentItem // Avoid animation short blinking of spinny during startup Component.onCompleted: indicatorTransition.enabled = true @@ -33,22 +34,17 @@ Item { key: "playposition" } - Item { + Control { id: indicatorContainer anchors.fill: parent visible: opacity > 0 - Item { - anchors.fill: parent - - data: Rectangle { - height: root.height / 2 - width: height / 12 - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - } - + contentItem: Rectangle { + height: root.height / 2 + width: height / 12 + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top } transform: Rotation { diff --git a/res/skins/QMLDemo/Mixxx/Controls/ToggleButton.qml b/res/skins/QMLDemo/Mixxx/Controls/ToggleButton.qml deleted file mode 100644 index f029bcc642c..00000000000 --- a/res/skins/QMLDemo/Mixxx/Controls/ToggleButton.qml +++ /dev/null @@ -1,37 +0,0 @@ -import Mixxx 0.1 as Mixxx -import QtQuick 2.12 -import QtQuick.Controls 2.12 - -Item { - id: root - - property alias group: control.group - property alias key: control.key - property alias icon: button.icon - property alias background: button.background - property alias state: buttonRect.state - default property alias states: buttonRect.states - - Rectangle { - id: buttonRect - - anchors.fill: parent - color: "transparent" - - Button { - id: button - - anchors.fill: parent - onPressed: control.value ? control.value = 0 : control.value = 1 - - Mixxx.ControlProxy { - id: control - - onValueChanged: root.state = control.value - } - - } - - } - -} diff --git a/res/skins/QMLDemo/OrientationToggleButton.qml b/res/skins/QMLDemo/OrientationToggleButton.qml new file mode 100644 index 00000000000..c255bf96b56 --- /dev/null +++ b/res/skins/QMLDemo/OrientationToggleButton.qml @@ -0,0 +1,92 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +AbstractButton { + id: root + + property string group // required + property string key // required + property alias orientation: control.value + property color color: "white" + + implicitWidth: 56 + implicitHeight: 26 + onClicked: control.value = Math.trunc(3 * pressX / root.width) + states: [ + State { + name: "left" + when: orientation == 0 + + PropertyChanges { + target: indicator + x: 0 + } + + }, + State { + name: "right" + when: orientation == 2 + + PropertyChanges { + target: indicator + x: parent.width - width + } + + }, + State { + name: "mid" + when: orientation == 1 + + PropertyChanges { + target: indicator + x: parent.width / 2 - width / 2 + } + + } + ] + + Mixxx.ControlProxy { + id: control + + group: root.group + key: root.key + } + + Item { + anchors.fill: root + anchors.leftMargin: 10 + anchors.rightMargin: 10 + anchors.topMargin: 2 + anchors.bottomMargin: 2 + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + height: 2 + color: root.color + } + + Rectangle { + id: indicator + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.margins: 5 + width: 3 + color: root.color + + Behavior on x { + NumberAnimation { + duration: 150 + } + + } + + } + + } + +} diff --git a/res/skins/QMLDemo/Slider.qml b/res/skins/QMLDemo/Slider.qml new file mode 100644 index 00000000000..be1786dee65 --- /dev/null +++ b/res/skins/QMLDemo/Slider.qml @@ -0,0 +1,32 @@ +import "." as Skin +import Mixxx.Controls 0.1 as MixxxControls +import QtQuick 2.12 +import "Theme" + +MixxxControls.Slider { + id: root + + property alias fg: handleImage.source + property alias bg: backgroundImage.source + + bar: true + barColor: Theme.sliderBarColor + barMargin: 10 + implicitWidth: handleImage.implicitWidth + 10 + implicitHeight: handleImage.implicitHeight + 10 + + handle: Image { + id: handleImage + + anchors.top: parent.top + source: "images/slider_handle.svg" + } + + background: Image { + id: backgroundImage + + anchors.fill: parent + anchors.margins: 10 + } + +} diff --git a/res/skins/QMLDemo/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml new file mode 100644 index 00000000000..1b9b678acbb --- /dev/null +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -0,0 +1,37 @@ +import QtQuick 2.12 +pragma Singleton + +QtObject { + property color white: "#e3d7fb" + property color yellow: "#fca001" + property color red: "#ea2a4e" + property color blue: "#01dcfc" + property color green: "#85c85b" + property color lightGray: "#747474" + property color lightGray2: "#b0b0b0" + property color midGray: "#696969" + property color darkGray: "#0f0f0f" + property color darkGray2: "#2e2e2e" + property color eqHighColor: white + property color eqMidColor: white + property color eqLowColor: white + property color eqFxColor: red + property color bpmSliderBarColor: green + property color volumeSliderBarColor: blue + property color gainKnobColor: blue + property color crossfaderOrientationColor: lightGray + property color crossfaderBarColor: red + property color toolbarBackgroundColor: darkGray2 + property color pflActiveButtonColor: blue + property color backgroundColor: "#1e1e20" + property color deckActiveColor: green + property color deckBackgroundColor: darkGray + property color deckLineColor: darkGray2 + property color deckTextColor: lightGray2 + property color buttonNormalColor: midGray + property color textColor: lightGray2 + property color toolbarActiveColor: white + property string fontFamily: "Open Sans" + property int textFontPixelSize: 14 + property int buttonFontPixelSize: 10 +} diff --git a/res/skins/QMLDemo/Theme/qmldir b/res/skins/QMLDemo/Theme/qmldir new file mode 100644 index 00000000000..5023b9dc1c4 --- /dev/null +++ b/res/skins/QMLDemo/Theme/qmldir @@ -0,0 +1 @@ +singleton Theme 0.1 Theme.qml diff --git a/res/skins/QMLDemo/WaveformOverview.qml b/res/skins/QMLDemo/WaveformOverview.qml index 8ed1da2f170..37690f74f94 100644 --- a/res/skins/QMLDemo/WaveformOverview.qml +++ b/res/skins/QMLDemo/WaveformOverview.qml @@ -1,11 +1,12 @@ import Mixxx 0.1 as Mixxx import QtQuick 2.12 import QtQuick.Shapes 1.12 +import "Theme" Item { id: root - required property string group + property string group // required states: [ State { @@ -119,14 +120,13 @@ Item { id: waveformContainer anchors.fill: parent - color: "#121213" + color: Theme.deckBackgroundColor Text { anchors.centerIn: parent - font.family: "Open Sans" - font.bold: true - font.pixelSize: 11 - color: "#777777" + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: Theme.deckTextColor text: "Waveform Placeholder" } @@ -140,10 +140,9 @@ Item { Text { anchors.centerIn: parent - font.family: "Open Sans" - font.bold: true - font.pixelSize: 11 - color: "#777777" + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: Theme.deckTextColor text: "Passthrough Enabled" } diff --git a/res/skins/QMLDemo/images/button.svg b/res/skins/QMLDemo/images/button.svg new file mode 100644 index 00000000000..c7f76d1717e --- /dev/null +++ b/res/skins/QMLDemo/images/button.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/button_pressed.svg b/res/skins/QMLDemo/images/button_pressed.svg new file mode 100644 index 00000000000..1c669f0ab31 --- /dev/null +++ b/res/skins/QMLDemo/images/button_pressed.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/icon_passthrough.svg b/res/skins/QMLDemo/images/icon_passthrough.svg new file mode 100644 index 00000000000..cd74c2b7f2d --- /dev/null +++ b/res/skins/QMLDemo/images/icon_passthrough.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/icon_quantize.svg b/res/skins/QMLDemo/images/icon_quantize.svg new file mode 100644 index 00000000000..63d974c43c9 --- /dev/null +++ b/res/skins/QMLDemo/images/icon_quantize.svg @@ -0,0 +1,35 @@ + + + + + + + image/svg+xml + + + + + + + + + diff --git a/res/skins/QMLDemo/images/knob.svg b/res/skins/QMLDemo/images/knob.svg new file mode 100644 index 00000000000..d75a207454f --- /dev/null +++ b/res/skins/QMLDemo/images/knob.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/slider_bpm.svg b/res/skins/QMLDemo/images/slider_bpm.svg new file mode 100644 index 00000000000..bdeb7176abb --- /dev/null +++ b/res/skins/QMLDemo/images/slider_bpm.svg @@ -0,0 +1,1812 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/skins/QMLDemo/images/slider_crossfader.svg b/res/skins/QMLDemo/images/slider_crossfader.svg new file mode 100644 index 00000000000..4f9f28ad4cf --- /dev/null +++ b/res/skins/QMLDemo/images/slider_crossfader.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/skins/QMLDemo/images/slider_handle.svg b/res/skins/QMLDemo/images/slider_handle.svg new file mode 100644 index 00000000000..58d3f8ae294 --- /dev/null +++ b/res/skins/QMLDemo/images/slider_handle.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/slider_handle_crossfader.svg b/res/skins/QMLDemo/images/slider_handle_crossfader.svg new file mode 100644 index 00000000000..4ceec575bd2 --- /dev/null +++ b/res/skins/QMLDemo/images/slider_handle_crossfader.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/res/skins/QMLDemo/images/slider_volume.svg b/res/skins/QMLDemo/images/slider_volume.svg new file mode 100644 index 00000000000..e9999d57630 --- /dev/null +++ b/res/skins/QMLDemo/images/slider_volume.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/main.qml b/res/skins/QMLDemo/main.qml index 275d50af2bd..1369972ccda 100644 --- a/res/skins/QMLDemo/main.qml +++ b/res/skins/QMLDemo/main.qml @@ -1,13 +1,17 @@ +import "." as Skin import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.11 +import "Theme" Rectangle { id: root + property alias show4decks: show4DecksButton.checked + width: 1920 height: 1080 - color: "#1e1e20" + color: Theme.backgroundColor visible: true Column { @@ -19,165 +23,59 @@ Rectangle { width: parent.width height: 36 - color: "#151517" - border.color: "#020202" - border.width: 1 + color: Theme.toolbarBackgroundColor radius: 1 Row { padding: 5 spacing: 5 - Button { - id: decksCDToggle - - width: 100 - height: 26 - text: "4 DECKS" - font.family: "Open Sans" - font.bold: true - font.pixelSize: 11 - onClicked: decksCD.stateHidden = !decksCD.stateHidden - states: [ - State { - when: decksCD.stateHidden - - PropertyChanges { - target: decksCDToggle - background.color: "#151517" - contentItem.color: "#777777" - } - - PropertyChanges { - target: decksCDToggleBgImage - source: "../LateNight/palemoon/buttons/btn___active.svg" - } - - }, - State { - when: !decksCD.stateHidden - - PropertyChanges { - target: decksCDToggle - background.color: "#777777" - contentItem.color: "#000000" - } - - PropertyChanges { - target: decksCDToggleBgImage - source: "../LateNight/palemoon/buttons/btn__.svg" - } - - } - ] - - contentItem: Text { - text: decksCDToggle.text - font: decksCDToggle.font - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - anchors.fill: parent - border.width: 2 - - Image { - id: decksCDToggleBgImage - - anchors.fill: parent - } - - } + Skin.Button { + id: show4DecksButton + text: "4 Decks" + activeColor: Theme.white + checkable: true } } } - DeckRow { - id: decksAB + Skin.DeckRow { + id: decks12 - width: root.width - height: 180 - leftDeck: "[Channel1]" - rightDeck: "[Channel2]" + leftDeckGroup: "[Channel1]" + rightDeckGroup: "[Channel2]" + width: parent.width - 10 + x: 5 } - DeckRow { - id: decksCD + Skin.CrossfaderRow { + id: crossfader - property bool stateHidden: true + crossfaderWidth: decks12.mixer.width + width: parent.width - 10 + x: 5 + } - function toggle() { - stateHidden = !stateHidden; - } + Skin.DeckRow { + id: decks34 - width: root.width - height: 180 - leftDeck: "[Channel3]" - rightDeck: "[Channel4]" - states: [ - State { - when: !decksCD.stateHidden - - PropertyChanges { - target: decksCD - opacity: 1 - visible: true - } - - }, - State { - when: decksCD.stateHidden - - PropertyChanges { - target: decksCD - opacity: 0 - visible: false - } + leftDeckGroup: "[Channel3]" + rightDeckGroup: "[Channel4]" + width: parent.width - 10 + x: 5 - } - ] - transitions: [ - Transition { - enabled: !decksCD.stateHidden - - SequentialAnimation { - NumberAnimation { - target: decksCD - property: "opacity" - duration: 150 - } - - PropertyAction { - target: decksCD - property: "visible" - } - - } - - }, - Transition { - enabled: decksCD.stateHidden - - SequentialAnimation { - PropertyAction { - target: decksCD - property: "visible" - } - - NumberAnimation { - target: decksCD - property: "opacity" - duration: 150 - } - - } + states: Skin.HiddenState { + when: !root.show4decks + target: decks34 + } + + transitions: Skin.HiddenTransition { + target: decks34 + } - } - ] } Library { diff --git a/src/skin/qml/qmlcontrolproxy.h b/src/skin/qml/qmlcontrolproxy.h index 8ecedee1f62..1e62590b0ee 100644 --- a/src/skin/qml/qmlcontrolproxy.h +++ b/src/skin/qml/qmlcontrolproxy.h @@ -14,14 +14,11 @@ namespace qml { class QmlControlProxy : public QObject, public QQmlParserStatus { Q_OBJECT Q_INTERFACES(QQmlParserStatus) - // The REQUIRED flag only exists in Qt 5.14 and later. -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - Q_PROPERTY(QString group READ getGroup WRITE setGroup NOTIFY groupChanged REQUIRED) - Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged REQUIRED) -#else + // TODO: The REQUIRED flag only exists in Qt 5.14 and later. Once we + // require that as minimum dependency, add it to the group and key + // properties. Q_PROPERTY(QString group READ getGroup WRITE setGroup NOTIFY groupChanged) Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged) -#endif Q_PROPERTY(QString keyValid READ isKeyValid NOTIFY keyValidChanged) Q_PROPERTY(QString initialized READ isInitialized NOTIFY initializedChanged) Q_PROPERTY(double value READ getValue WRITE setValue NOTIFY valueChanged)