-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
feat: controller screen renderer #11407
Changes from 30 commits
10cfd2f
ba4d030
b8b7f91
f1487a0
feeb892
6d5fb99
a204405
2be3c21
676cd90
61ec210
6bb2235
e864684
10cb8a6
ede6993
c815d09
42158b5
ea12d82
b1b9e64
a87fd88
633c84d
ee6dfe5
d60c2bd
d9b135c
65d3286
b6c158b
5861649
b63577c
cb9a5c2
6197a07
df39da0
d7ce6d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?xml version='1.0' encoding='utf-8'?> | ||
<MixxxControllerPreset mixxxVersion="2.4.0" schemaVersion="1"> | ||
<info> | ||
<name>Dummy Device (Screens)</name> | ||
<author>A. Colombier</author> | ||
<description>Dummy device screens</description> | ||
<devices> | ||
<product protocol="hid" vendor_id="0xdead" product_id="0xbeaf" /> | ||
</devices> | ||
</info> | ||
<controller id="DummyDevice"> | ||
<screens> | ||
<screen identifier="main" width="480" height="360" targetFps="20" pixelType="RBGA" splashoff="500" /> | ||
<screen identifier="jog" width="128" height="128" targetFps="5" pixelType="RBGA" /> | ||
</screens> | ||
<scriptfiles> | ||
<file filename="DummyDeviceDefaultScreen.qml" /> | ||
</scriptfiles> | ||
<qmllibraries> | ||
</qmllibraries> | ||
</controller> | ||
</MixxxControllerPreset> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
import QtQuick 2.15 | ||
import QtQuick.Window 2.3 | ||
|
||
import QtQuick.Controls 2.15 | ||
import QtQuick.Shapes 1.11 | ||
import QtQuick.Layouts 1.3 | ||
import QtQuick.Window 2.15 | ||
|
||
import Qt5Compat.GraphicalEffects | ||
|
||
import Mixxx 1.0 as Mixxx | ||
import Mixxx.Controls 1.0 as MixxxControls | ||
|
||
import "." as Skin | ||
|
||
Item { | ||
id: root | ||
|
||
required property string screenId | ||
property color fontColor: Qt.rgba(242/255,242/255,242/255, 1) | ||
property color smallBoxBorder: Qt.rgba(44/255,44/255,44/255, 1) | ||
|
||
property string group: "[Channel1]" | ||
property var deckPlayer: Mixxx.PlayerManager.getPlayer(root.group) | ||
|
||
function init(controlerName, isDebug) { | ||
console.log(`Screen ${root.screenId} has started`) | ||
switch (root.screenId) { | ||
case "jog": | ||
loader.sourceComponent = jog | ||
break; | ||
default: | ||
loader.sourceComponent = main | ||
} | ||
} | ||
|
||
function shutdown() { | ||
console.log(`Screen ${root.screenId} is stopping`) | ||
loader.sourceComponent = splash | ||
} | ||
|
||
// function transformFrame(input: ArrayBuffer, timestamp: date) { | ||
acolombier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
function transformFrame(input, timestamp) { | ||
return new ArrayBuffer(0); | ||
} | ||
|
||
Mixxx.ControlProxy { | ||
group: root.group | ||
key: "track_loaded" | ||
|
||
onValueChanged: (value) => { | ||
deckPlayer = Mixxx.PlayerManager.getPlayer(root.group) | ||
} | ||
} | ||
|
||
Timer { | ||
id: channelchange | ||
|
||
interval: 2000 | ||
repeat: true | ||
running: true | ||
|
||
onTriggered: { | ||
root.group = root.group === "[Channel1]" ? "[Channel2]" : "[Channel1]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we care about 4-deck support here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "Dummy Screen" mapping was only put there to allow anyone to test this feature without a S4 Mk3 device. I think this mapping can be removed before we merge There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that seems like it would be a useful feature, though? would this help developers create screen designs for controllers of arbitrary sizes without needing to own the devices? Also too, it might help with the creation of tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (and we will need to test switchable 4 deck support, I would imagine) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps this could go in the tools folder then? My concern being, we probably shouldn't ship this mapping as part of the the distribution. This could however be a good starting point for anyone wishing to test this feature and make the most of the screen rendering without using the physical device, which may help for design and testing. What do you think? Maybe I can put that as a snippet in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally it could be included in the developer builds only, so that it is still regularly built by CI. It could be in something like res/controllers/testing/ . But if it's easier to put it somewhere else for now that's fine too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
deckPlayer = Mixxx.PlayerManager.getPlayer(root.group) | ||
} | ||
} | ||
|
||
Component { | ||
id: splash | ||
Rectangle { | ||
color: "black" | ||
anchors.fill: parent | ||
Image { | ||
anchors.fill: parent | ||
fillMode: Image.PreserveAspectFit | ||
source: "../images/templates/logo_mixxx.png" | ||
} | ||
} | ||
} | ||
|
||
Component { | ||
id: jog | ||
|
||
Rectangle { | ||
anchors.fill: parent | ||
color: "black" | ||
|
||
Image { | ||
id: artwork | ||
anchors.fill: parent | ||
visible: deckPlayer.trackLocationUrl.toString().length !== 0 | ||
|
||
source: deckPlayer.coverArtUrl ?? "../images/templates/logo_mixxx.png" | ||
height: 100 | ||
width: 100 | ||
fillMode: Image.PreserveAspectFit | ||
} | ||
|
||
Text { | ||
visible: deckPlayer.trackLocationUrl.toString().length === 0 | ||
|
||
text: qsTr("No Track Loaded") | ||
font.pixelSize: 12 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: "white" | ||
} | ||
} | ||
} | ||
|
||
Component { | ||
id: main | ||
|
||
Rectangle { | ||
id: debugValue | ||
anchors.fill: parent | ||
color: 'black' | ||
|
||
antialiasing: true | ||
|
||
ColumnLayout { | ||
id: column | ||
anchors.fill: parent | ||
anchors.leftMargin: 0 | ||
anchors.rightMargin: 0 | ||
anchors.topMargin: 0 | ||
anchors.bottomMargin: 0 | ||
spacing: 6 | ||
|
||
RowLayout { | ||
Layout.fillWidth: true | ||
spacing: 0 | ||
|
||
Repeater { | ||
id: debugColor | ||
|
||
model: [ | ||
"black", | ||
"white", | ||
"red", | ||
"green", | ||
"blue", | ||
Qt.rgba(0, 1, 1), | ||
] | ||
|
||
Rectangle { | ||
required property var modelData | ||
|
||
color: modelData | ||
Layout.fillWidth: true | ||
height: 80 | ||
} | ||
} | ||
} | ||
|
||
RowLayout { | ||
anchors.leftMargin: 6 | ||
anchors.rightMargin: 6 | ||
anchors.topMargin: 6 | ||
anchors.bottomMargin: 6 | ||
|
||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
spacing: 6 | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
Text { | ||
text: qsTr("Group") | ||
font.pixelSize: 24 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: fontColor | ||
} | ||
} | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
Text { | ||
text: `${root.group}` | ||
font.pixelSize: 24 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: fontColor | ||
} | ||
} | ||
} | ||
|
||
RowLayout { | ||
anchors.leftMargin: 6 | ||
anchors.rightMargin: 6 | ||
anchors.topMargin: 6 | ||
anchors.bottomMargin: 6 | ||
|
||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
spacing: 6 | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
Text { | ||
text: qsTr("Widget") | ||
font.pixelSize: 24 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: fontColor | ||
} | ||
} | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
|
||
Skin.HotcueButton { | ||
anchors.fill: parent | ||
|
||
hotcueNumber: 1 | ||
group: root.group | ||
} | ||
} | ||
} | ||
|
||
Repeater { | ||
model: [{ | ||
controllerKey: "beatloop_size", | ||
title: "Beatloop Size" | ||
}, { | ||
controllerKey: "track_samples", | ||
title: "Track sample" | ||
}, { | ||
controllerKey: "track_samplerate", | ||
title: "Track sample rate" | ||
}, { | ||
controllerKey: "playposition", | ||
title: "Play position" | ||
}, { | ||
controllerKey: "rate_ratio", | ||
title: "Rate ratio" | ||
}, { | ||
controllerKey: "waveform_zoom", | ||
title: "Waveform zoom" | ||
} | ||
] | ||
|
||
RowLayout { | ||
id: row | ||
anchors.leftMargin: 6 | ||
anchors.rightMargin: 6 | ||
anchors.topMargin: 6 | ||
anchors.bottomMargin: 6 | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
spacing: 6 | ||
required property var modelData | ||
|
||
Mixxx.ControlProxy { | ||
id: mixxxValue | ||
group: root.group | ||
key: modelData.controllerKey | ||
} | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
Text { | ||
text: qsTr(modelData.title) | ||
font.pixelSize: 24 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: fontColor | ||
} | ||
} | ||
|
||
Rectangle { | ||
color: 'transparent' | ||
Layout.fillWidth: true | ||
Layout.fillHeight: true | ||
Text { | ||
text: `${mixxxValue.value}` | ||
font.pixelSize: 24 | ||
font.family: "Noto Sans" | ||
font.letterSpacing: -1 | ||
color: fontColor | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
Loader { | ||
id: loader | ||
anchors.fill: parent | ||
sourceComponent: splash | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this PR seems to have broken the build with QML on macOS (which is the default) and since we've disabled it in CI, some issues seem to have flown under the radar here... I'll have a quick look at how easy that would be to fix