1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-12 17:14:00 +02:00

restructured QML

This commit is contained in:
Michael Zanetti
2012-07-14 16:19:35 +02:00
parent 71eb1e916a
commit 710e570845
13 changed files with 445 additions and 274 deletions

View File

@@ -3,6 +3,11 @@ import QtQuick 1.1
Item {
id: root
// Should the artist + track labels be painted
property bool showLabels: true
// Should the play button be painted on mouse hover?
property bool showPlayButton: false
// Labels & Cover
property string artistName
property string trackName
@@ -22,13 +27,15 @@ Item {
// will be emitted when the on hower play button is clicked
signal playClicked()
// will be emitted when the cover is clicked
signal clicked()
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: print("cover clicked")
onClicked: root.clicked();
}
@@ -53,10 +60,10 @@ Item {
height: 32
anchors.margins: 5
color: "black"
opacity: 0.5
opacity: showLabels ? 0.5 : 0
radius: 3
}
Text {
color: "white"
font.bold: true
@@ -65,6 +72,7 @@ Item {
anchors.margins: 2
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
opacity: showLabels ? 1 : 0
}
Text {
color: "white"
@@ -73,6 +81,7 @@ Item {
anchors.margins: 2
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
opacity: showLabels ? 1 : 0
}
}
@@ -130,11 +139,9 @@ Item {
Image {
id: playButton
visible: showPlayButton ? mouseArea.containsMouse : false
source: "../images/play-rest.png"
anchors.centerIn: parent
// width:
// height: 32
visible: mouseArea.containsMouse
MouseArea {
anchors.fill: parent
onClicked: root.playClicked();

View File

@@ -0,0 +1,53 @@
import QtQuick 1.1
import tomahawk 1.0
Item {
id: fineTuneView
property color textColor: "white"
signal done();
Grid {
anchors.fill: parent
anchors.margins: 50
Text {
color: fineTuneView.textColor
text: "Name"
}
TextInput {
id: stationName
width: 200
text: echonestStation.name
//onTextChanged: echonestStation.
}
}
Rectangle {
id: configureButton
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
color: "gray"
height: 20
width: 150
radius: 10
//opacity: 0
Text {
anchors.centerIn: parent
text: "configure"
color: "white"
}
MouseArea {
anchors.fill: parent
onClicked: {
fineTuneView.done();
}
}
}
}

View File

@@ -7,265 +7,56 @@ Rectangle {
anchors.fill: parent
state: echonestStation.configured ? "list" : "configure"
property int coverSize: 230
onWidthChanged: {
print("width changed to", width)
coverView.model = dynamicModel
VisualItemModel {
id: stationVisualModel
TagCloud {
height: scene.height
width: scene.width
model: generator.styles()
opacity: echonestStation.configured ? 0 : 1
onTagClicked: {
echonestStation.setMainControl( item );
stationListView.incrementCurrentIndex();
}
Behavior on opacity {
NumberAnimation { duration: 300 }
}
}
StationView {
coverSize: 250
height: scene.height
width: scene.width
onConfigure: stationListView.incrementCurrentIndex();
}
StationConfig {
height: scene.height
width: scene.width
onDone: stationListView.decrementCurrentIndex();
}
}
states: [
State {
name: "configure"
PropertyChanges { target: styleCloud; anchors.leftMargin: 0 }
PropertyChanges { target: configureButton; opacity: 1 }
},
State {
name: "finetune"
PropertyChanges { target: fineTuneView; anchors.rightMargin: 0 }
PropertyChanges { target: configureButton; opacity: 1 }
}
]
transitions: [
Transition {
NumberAnimation {
target: styleCloud
properties: "anchors.leftMargin"; easing.type: Easing.InOutQuad; duration: 500
}
NumberAnimation {
target: fineTuneView
properties: "anchors.rightMargin"; easing.type: Easing.InOutQuad; duration: 500
}
NumberAnimation {
target: configureButton
properties: "opacity"; easing.type: Easing.InOutQuad; duration: 500
}
}
]
PathView {
id: coverView
ListView {
id: stationListView
anchors.fill: parent
contentHeight: scene.height
contentWidth: scene.width
orientation: ListView.Horizontal
model: stationVisualModel
interactive: false
highlightMoveDuration: 400
Component.onCompleted: {
print("pathview created:", scene.width)
}
preferredHighlightBegin: 0.1 // scene.width / 11000
preferredHighlightEnd: preferredHighlightBegin
pathItemCount: 5
//highlightMoveDuration: 500
model: dynamicModel
currentIndex: currentlyPlayedIndex
property int pathStartX: width - scene.coverSize
property int pathStartY: height / 2
delegate: CoverImage {
height: scene.coverSize
width: scene.coverSize
artistName: model.artistName
trackName: model.trackName
artworkId: index
scale: PathView.itemScale
itemBrightness: PathView.itemBrightness
opacity: PathView.itemOpacity
z: x
onPlayClicked: echonestStation.playItem( index )
}
path: Path {
startX: coverView.pathStartX
startY: coverView.pathStartY
PathAttribute { name: "itemOpacity"; value: 0 }
PathAttribute { name: "itemBrightness"; value: 0 }
PathAttribute { name: "itemScale"; value: 1.5 }
PathLine { x: coverView.pathStartX * 9/10 ; y: coverView.pathStartY * 9/10 }
PathPercent { value: .1 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 1 }
PathAttribute { name: "itemScale"; value: 1.0 }
PathLine { x: coverView.pathStartX * .5; y: coverView.pathStartY * .7}
PathPercent { value: .4 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 1 }
PathAttribute { name: "itemScale"; value: 0.6 }
PathLine { x: coverView.pathStartX * .25 ; y: coverView.pathStartY * .25 }
PathPercent { value: .75 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: .5 }
PathAttribute { name: "itemScale"; value: 0.4 }
PathLine { x: 0; y: 0 }
PathPercent { value: 1 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 0 }
PathAttribute { name: "itemScale"; value: 0.2 }
}
states: [
State {
name: "normal"
PropertyChanges { target: coverView; anchors.rightMargin: 0 }
},
State {
name: "shrinked"
PropertyChanges { target: coverView; anchors.rightMargin: scene.width / 3 }
}
]
transitions: [
Transition {
NumberAnimation {
target: coverView
properties: "anchors.rightMargin"; easing.type: Easing.InOutQuad; duration: 500
}
}
]
}
Item {
id: styleCloud
anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
anchors.leftMargin: scene.width
width: scene.width
function randomNumber(min, max) {
var date = new Date();
return (max - min) * Math.random(date.getSeconds()) + min
}
Flow {
anchors.centerIn: parent
width: parent.width - 100
//model: controlModel
spacing: 3
Timer {
interval: 5000
running: false
repeat: true
onTriggered: {
for(var i = 0; i < cloudRepeater.count; i++) {
var item = cloudRepeater.itemAt(i);
if(item.itemScale > 0.6) {
item.itemScale = Math.random();
} else {
item.itemScale = Math.random();
}
}
}
}
Repeater {
id: cloudRepeater
model: generator.styles()
delegate: Item {
id: cloudItem
width: delegateText.width * scale
height: 28
property double itemScale: Math.random()
scale: itemScale
Text {
id: delegateText
color: "white"
//text: controlModel.controlAt( index ).summary
text: modelData
font.pixelSize: 28
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: styleCloud.randomNumber(0, 15)
}
MouseArea {
hoverEnabled: true
anchors.fill: parent
onClicked: echonestStation.setMainControl(modelData);
onMousePositionChanged: {
cloudItem.scale = 1;
delegateTimer.restart();
}
}
Timer {
id: delegateTimer
interval: 3000
repeat: false
onTriggered: cloudItem.scale = cloudItem.itemScale
}
Behavior on scale {
NumberAnimation { easing: Easing.Linear; duration: 1000 }
}
}
}
}
}
Item {
id: fineTuneView
anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
anchors.rightMargin: -width
width: scene.width / 2
property color textColor: "white"
Rectangle {
anchors.fill: parent
anchors.margins: 30
color: "gray"
border.width: 2
border.color: "white"
radius: 20
}
Grid {
Text {
color: fineTuneView.textColor
text: "Name"
}
TextInput {
id: stationName
//onTextChanged: echonestStation.
}
}
}
Rectangle {
id: configureButton
anchors.right: parent.right
anchors.rightMargin: 20
anchors.verticalCenter: parent.verticalCenter
color: "gray"
height: 50
width: 50
radius: 25
//opacity: 0
Text {
anchors.centerIn: parent
text: "configure"
}
MouseArea {
anchors.fill: parent
onClicked: {
print("changing scene state to", scene.state)
if( scene.state === "list" ) {
scene.state = "finetune";
coverView.state = "shrinked"
} else {
scene.state = "list";
coverView.state = "normal"
}
print("changed scene state to", scene.state)
if ( echonestStation.configured ) {
currentIndex = 1
}
}
}

201
data/qml/StationView.qml Normal file
View File

@@ -0,0 +1,201 @@
import QtQuick 1.1
import tomahawk 1.0
Item {
id: root
property int coverSize
signal configure()
PathView {
id: coverView
anchors.fill: parent
anchors.rightMargin: parent.width / 3
preferredHighlightBegin: 0.2 // scene.width / 11000
preferredHighlightEnd: preferredHighlightBegin
pathItemCount: 5
//highlightMoveDuration: 500
model: dynamicModel
currentIndex: currentlyPlayedIndex
property int pathStartX: width / 2
property int pathStartY: height / 2
delegate: CoverImage {
height: root.coverSize
width: root.coverSize
showLabels: false
//artistName: model.artistName
//trackName: model.trackName
artworkId: index
scale: PathView.itemScale
itemBrightness: PathView.itemBrightness
opacity: PathView.itemOpacity
z: x
onClicked: {
if ( currentlyPlayedIndex !==-1 ) {
echonestStation.playItem( index )
}
}
}
path: Path {
startX: coverView.pathStartX
startY: coverView.pathStartY
PathAttribute { name: "itemOpacity"; value: 0 }
PathAttribute { name: "itemBrightness"; value: 0 }
PathAttribute { name: "itemScale"; value: 1.5 }
PathLine { x: coverView.pathStartX * 0.9 ; y: coverView.pathStartY * 0.9 }
PathPercent { value: .2 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 1 }
PathAttribute { name: "itemScale"; value: 1 }
PathLine { x: coverView.pathStartX * .5; y: coverView.pathStartY * .5}
PathPercent { value: .3 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 1 }
PathAttribute { name: "itemScale"; value: 0.5 }
// PathLine { x: coverView.pathStartX * .25 ; y: coverView.pathStartY * .25 }
// PathPercent { value: .75 }
// PathAttribute { name: "itemOpacity"; value: 1 }
// PathAttribute { name: "itemBrightness"; value: .5 }
// PathAttribute { name: "itemScale"; value: 0.4 }
PathLine { x: 0; y: 0 }
PathPercent { value: 1 }
PathAttribute { name: "itemOpacity"; value: 1 }
PathAttribute { name: "itemBrightness"; value: 0 }
PathAttribute { name: "itemScale"; value: 0.1 }
}
}
Item {
anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
anchors.margins: 50
width: scene.width / 3
Column {
anchors { left: parent.left; top: parent.top; right: parent.right }
Text {
color: "white"
font.pixelSize: 16
width: parent.width
elide: Text.ElideRight
text: "Station:"
}
Text {
color: "white"
font.pixelSize: 24
font.bold: true
width: parent.width
elide: Text.ElideRight
text: echonestStation.name
}
}
Column {
anchors.right: parent.right
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: scene.width / 3
Text {
color: "white"
font.pixelSize: 16
width: parent.width
elide: Text.ElideRight
text: "Now Playing:"
visible: currentlyPlayedIndex !== -1
}
Rectangle {
height: 64
width: parent.width
radius: 32
border.width: 2
border.color: "white"
color: startPlayingMouseArea.containsMouse ? "blue" : "gray"
visible: currentlyPlayedIndex === -1
Image {
id: image
source: "../images/play-rest.png"
anchors.left: parent.left
anchors.margins: 10
anchors.verticalCenter: parent.verticalCenter
}
Text {
color: "white"
font.pixelSize: 24
anchors.left: image.right
anchors.margins: 10
anchors.verticalCenter: parent.verticalCenter
width: parent.width - 30 - image.width
elide: Text.ElideRight
text: "Start playing"
}
MouseArea {
id: startPlayingMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: echonestStation.playItem( 0 );
}
}
Text {
color: "white"
font.pixelSize: 24
width: parent.width
elide: Text.ElideRight
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).name
}
Text {
color: "white"
font.pixelSize: 20
width: parent.width
elide: Text.ElideRight
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).artistName
}
Text {
color: "white"
font.pixelSize: 20
width: parent.width
elide: Text.ElideRight
text: coverView.model.itemFromIndex( currentlyPlayedIndex ).albumName
}
}
}
Rectangle {
id: configureButton
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
color: "gray"
height: 20
width: 150
radius: 10
//opacity: 0
Text {
anchors.centerIn: parent
text: "configure"
color: "white"
}
MouseArea {
anchors.fill: parent
onClicked: {
root.configure();
}
}
}
}

81
data/qml/TagCloud.qml Normal file
View File

@@ -0,0 +1,81 @@
import QtQuick 1.1
import tomahawk 1.0
Item {
id: tagCloud
property variant model: 10
signal tagClicked( string item )
function randomNumber(min, max) {
var date = new Date();
return (max - min) * Math.random(date.getSeconds()) + min
}
Flow {
anchors.centerIn: parent
width: parent.width - 100
//model: controlModel
spacing: 3
Timer {
interval: 5000
running: false
repeat: true
onTriggered: {
for(var i = 0; i < cloudRepeater.count; i++) {
var item = cloudRepeater.itemAt(i);
if(item.itemScale > 0.6) {
item.itemScale = Math.random();
} else {
item.itemScale = Math.random();
}
}
}
}
Repeater {
id: cloudRepeater
model: tagCloud.model
delegate: Item {
id: cloudItem
width: delegateText.width * scale
height: 28
property double itemScale: Math.random()
scale: itemScale
Text {
id: delegateText
color: "white"
//text: controlModel.controlAt( index ).summary
text: "bla" + modelData
font.pixelSize: 28
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: tagCloud.randomNumber(0, 15)
}
MouseArea {
hoverEnabled: true
anchors.fill: parent
onClicked: tagCloud.tagClicked( modelData )
onMousePositionChanged: {
cloudItem.scale = 1;
delegateTimer.restart();
}
}
Timer {
id: delegateTimer
interval: 3000
repeat: false
onTriggered: cloudItem.scale = cloudItem.itemScale
}
Behavior on scale {
NumberAnimation { easing: Easing.Linear; duration: 1000 }
}
}
}
}
}