mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-11 16:44:05 +02:00
* Imported QML resources.
This commit is contained in:
committed by
Michael Zanetti
parent
09c272a07c
commit
17eeae9a8f
21
data/qml/DeclarativeHeader.qml
Normal file
21
data/qml/DeclarativeHeader.qml
Normal file
@@ -0,0 +1,21 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "tomahawkimports"
|
||||
|
||||
// Only to be used together with DeclarativeHeader C++ class
|
||||
// If you want to use the header in QML, use FlexibleHeader
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
FlexibleHeader {
|
||||
anchors.fill: parent
|
||||
icon: iconSource
|
||||
title: caption
|
||||
subtitle: description
|
||||
buttonModel: buttonList
|
||||
|
||||
onSearchTextChanged: mainView.setFilterText(searchText)
|
||||
onCurrentButtonIndexChanged: mainView.viewModeSelected(currentButtonIndex)
|
||||
}
|
||||
}
|
65
data/qml/QmlGridView.qml
Normal file
65
data/qml/QmlGridView.qml
Normal file
@@ -0,0 +1,65 @@
|
||||
import QtQuick 1.1
|
||||
//import tomahawk 1.0
|
||||
import "tomahawkimports"
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
|
||||
Text {
|
||||
id: fontMetrics
|
||||
text: "Here's some sample text"
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
GridView {
|
||||
id: gridView
|
||||
anchors.fill: parent
|
||||
//anchors.rightMargin: scrollBar.width
|
||||
|
||||
cellHeight: cellWidth
|
||||
cellWidth: calculateCoverSize(gridView.width - 3)
|
||||
|
||||
cacheBuffer: cellHeight * 5
|
||||
|
||||
function calculateCoverSize(rectWidth) {
|
||||
var itemWidth = fontMetrics.width;
|
||||
var itemsPerRow = Math.max( 1, Math.floor( rectWidth / itemWidth ) );
|
||||
|
||||
var remSpace = rectWidth - ( itemsPerRow * itemWidth );
|
||||
var extraSpace = remSpace / itemsPerRow;
|
||||
return itemWidth + extraSpace;
|
||||
|
||||
}
|
||||
|
||||
model: mainModel
|
||||
|
||||
delegate: CoverImage {
|
||||
height: gridView.cellHeight// * 0.95
|
||||
width: gridView.cellWidth// * 0.95
|
||||
|
||||
showLabels: true
|
||||
showMirror: false
|
||||
artistName: model.artistName
|
||||
trackName: model.trackName
|
||||
artworkId: model.coverID
|
||||
showPlayButton: true
|
||||
currentlyPlaying: isPlaying
|
||||
smooth: !gridView.moving
|
||||
|
||||
onClicked: {
|
||||
rootView.onItemClicked(index)
|
||||
}
|
||||
onPlayClicked: {
|
||||
rootView.onItemPlayClicked(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: scrollBar
|
||||
listView: gridView
|
||||
orientation: Qt.Vertical
|
||||
margin: -width
|
||||
}
|
||||
}
|
34
data/qml/SpinnerTest.qml
Normal file
34
data/qml/SpinnerTest.qml
Normal file
@@ -0,0 +1,34 @@
|
||||
import QtQuick 1.1
|
||||
import "tomahawkimports"
|
||||
|
||||
Rectangle {
|
||||
width: 1400
|
||||
height: 900
|
||||
color: "black"
|
||||
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: 200
|
||||
height: 200
|
||||
width: 200
|
||||
}
|
||||
|
||||
Image {
|
||||
id: svgSpinner
|
||||
source: "../images/loading-animation.svg"
|
||||
smooth: true
|
||||
height: 200
|
||||
width: 200
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: -200
|
||||
|
||||
Timer {
|
||||
running: true
|
||||
repeat: true
|
||||
interval: 200
|
||||
onTriggered: svgSpinner.rotation += 360 / 12
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
162
data/qml/StationView.qml
Normal file
162
data/qml/StationView.qml
Normal file
@@ -0,0 +1,162 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "tomahawkimports"
|
||||
import "stations"
|
||||
Rectangle {
|
||||
id: scene
|
||||
color: "black"
|
||||
anchors.fill: parent
|
||||
state: "list"
|
||||
|
||||
FlexibleHeader {
|
||||
id: header
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
height: defaultFontHeight * 4
|
||||
width: parent.width
|
||||
icon: "../images/station.svg"
|
||||
title: mainView.title
|
||||
subtitle: generator.summary
|
||||
showSearchField: false
|
||||
showBackButton: stationListView.currentIndex > 0
|
||||
showNextButton: stationListView.currentIndex == 2
|
||||
nextButtonText: "Save"
|
||||
|
||||
z: 1 //cover albumcovers that may leave their area
|
||||
|
||||
onBackPressed: stationListView.decrementCurrentIndex()
|
||||
onNextPressed: stationListView.incrementCurrentIndex()
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: modeModel
|
||||
ListElement { label: "By Artist"; image: "../../images/station-artist.svg"; creatorContent: "stations/CreateByArtist.qml" }
|
||||
ListElement { label: "By Genre"; image: "../../images/station-genre.svg"; creatorContent: "stations/CreateByGenre.qml" }
|
||||
ListElement { label: "By Year"; image: "../../images/station-year.svg"; creatorContent: "year" }
|
||||
}
|
||||
|
||||
VisualItemModel {
|
||||
id: stationVisualModel
|
||||
|
||||
StationCreatorPage1 {
|
||||
height: scene.height - header.height
|
||||
width: scene.width
|
||||
model: modeModel
|
||||
|
||||
onItemClicked: {
|
||||
stationCreator.content = modeModel.get(index).creatorContent
|
||||
stationListView.incrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
StationCreatorPage2 {
|
||||
id: stationCreator
|
||||
height: stationListView.height
|
||||
width: stationListView.width
|
||||
|
||||
onNext: stationListView.incrementCurrentIndex()
|
||||
}
|
||||
|
||||
Item {
|
||||
id: stationItem
|
||||
height: stationListView.height
|
||||
width: stationListView.width
|
||||
|
||||
CoverFlip {
|
||||
id: coverView
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
interactive: false
|
||||
|
||||
backgroundColor: scene.color
|
||||
|
||||
model: dynamicModel
|
||||
currentIndex: currentlyPlayedIndex
|
||||
|
||||
onItemPlayPauseClicked: {
|
||||
mainView.playItem(index)
|
||||
}
|
||||
|
||||
onItemClicked: {
|
||||
mainView.playItem(index)
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "empty"; when: mainView.loading
|
||||
PropertyChanges {
|
||||
target: coverView
|
||||
anchors.rightMargin: -coverView.width
|
||||
anchors.topMargin: - coverView.height
|
||||
scale: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "empty"
|
||||
to: "*"
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin,anchors.rightMargin,scale"
|
||||
duration: 1000
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
// Behavior on anchors.topMargin {
|
||||
// NumberAnimation { duration: 500 }
|
||||
// }
|
||||
// Behavior on anchors.rightMargin {
|
||||
// NumberAnimation { duration: 500 }
|
||||
// }
|
||||
// Behavior on scale {
|
||||
// NumberAnimation { duration: 500 }
|
||||
// }
|
||||
|
||||
}
|
||||
BusyIndicator {
|
||||
id: busyIndicator
|
||||
anchors.centerIn: parent
|
||||
height: defaultFontHeight * 4
|
||||
width: height
|
||||
|
||||
opacity: mainView.loading ? 1 : 0
|
||||
running: mainView.loading
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ListView {
|
||||
id: stationListView
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: header.bottom
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
contentHeight: height
|
||||
contentWidth: width
|
||||
orientation: ListView.Horizontal
|
||||
model: stationVisualModel
|
||||
interactive: false
|
||||
highlightMoveDuration: 300
|
||||
|
||||
onHeightChanged: {
|
||||
contentHeight = scene.height
|
||||
}
|
||||
onWidthChanged: {
|
||||
contentWidth = scene.width
|
||||
}
|
||||
}
|
||||
|
||||
}
|
69
data/qml/stations/CreateByArtist.qml
Normal file
69
data/qml/stations/CreateByArtist.qml
Normal file
@@ -0,0 +1,69 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "../tomahawkimports"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
signal done()
|
||||
|
||||
function createStation(artist) {
|
||||
mainView.startStationFromArtist(artist)
|
||||
root.done()
|
||||
}
|
||||
|
||||
Column {
|
||||
id: upperColumn
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: parent.height
|
||||
width: defaultFontHeight * 30
|
||||
anchors.bottomMargin: defaultFontHeight
|
||||
spacing: defaultFontHeight
|
||||
|
||||
HeaderLabel {
|
||||
id: headerText
|
||||
text: "Create station by artist..."
|
||||
}
|
||||
|
||||
Row {
|
||||
height: artistInputField.height
|
||||
width: parent.width
|
||||
spacing: defaultFontHeight * 0.5
|
||||
|
||||
InputField {
|
||||
id: artistInputField
|
||||
width: parent.width - createFromInputButton.width - parent.spacing
|
||||
|
||||
onAccepted: createStation(text)
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: createFromInputButton
|
||||
text: "Go!"
|
||||
enabled: artistInputField.text.length > 2
|
||||
onClicked: createStation(artistInputField.text)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: parent.height - headerText.height - artistInputField.height - parent.spacing * 3
|
||||
width: parent.width
|
||||
ArtistView {
|
||||
id: artistView
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
model: artistChartsModel
|
||||
clip: true
|
||||
delegateHeight: defaultFontHeight * 6
|
||||
|
||||
onItemClicked: {
|
||||
createStation(artistChartsModel.itemFromIndex(index).artistName);
|
||||
}
|
||||
}
|
||||
ScrollBar {
|
||||
listView: artistView
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
88
data/qml/stations/CreateByGenre.qml
Normal file
88
data/qml/stations/CreateByGenre.qml
Normal file
@@ -0,0 +1,88 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "../tomahawkimports"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
signal done()
|
||||
|
||||
function createStation(genre) {
|
||||
mainView.startStationFromGenre(genre)
|
||||
root.done()
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: styleModel
|
||||
ListElement { modelData: "acoustic" }
|
||||
ListElement { modelData: "alternative" }
|
||||
ListElement { modelData: "alternative rock" }
|
||||
ListElement { modelData: "classic" }
|
||||
ListElement { modelData: "folk" }
|
||||
ListElement { modelData: "indie" }
|
||||
ListElement { modelData: "pop" }
|
||||
ListElement { modelData: "rock" }
|
||||
ListElement { modelData: "hip-hop" }
|
||||
ListElement { modelData: "punk" }
|
||||
ListElement { modelData: "grunge" }
|
||||
ListElement { modelData: "indie" }
|
||||
ListElement { modelData: "electronic" }
|
||||
ListElement { modelData: "country" }
|
||||
ListElement { modelData: "jazz" }
|
||||
ListElement { modelData: "psychodelic" }
|
||||
ListElement { modelData: "soundtrack" }
|
||||
ListElement { modelData: "reggae" }
|
||||
ListElement { modelData: "house" }
|
||||
ListElement { modelData: "drum and base" }
|
||||
}
|
||||
|
||||
Column {
|
||||
id: upperColumn
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: defaultFontHeight
|
||||
spacing: defaultFontHeight
|
||||
|
||||
HeaderLabel {
|
||||
id: headerText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "Create station by genre..."
|
||||
}
|
||||
|
||||
Row {
|
||||
width: defaultFontHeight * 30
|
||||
height: genreInputField.height
|
||||
spacing: defaultFontHeight * 0.5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
InputField {
|
||||
id: genreInputField
|
||||
width: parent.width - createFromInputButton.width - parent.spacing
|
||||
|
||||
onAccepted: createStation(text);
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: createFromInputButton
|
||||
text: "Go!"
|
||||
height: genreInputField.height
|
||||
enabled: genreInputField.text.length > 2
|
||||
onClicked: createStation(genreInputField.text)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: parent.height - headerText.height - genreInputField.height
|
||||
width: parent.width
|
||||
TagCloud {
|
||||
anchors.fill: parent
|
||||
anchors.margins: parent.width / 6
|
||||
model: styleModel
|
||||
|
||||
onTagClicked: {
|
||||
root.createStation(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
data/qml/stations/StationConfig.qml
Normal file
79
data/qml/stations/StationConfig.qml
Normal file
@@ -0,0 +1,79 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "tomahawkimports"
|
||||
|
||||
Item {
|
||||
id: fineTuneView
|
||||
|
||||
property color textColor: "white"
|
||||
|
||||
signal done();
|
||||
|
||||
Grid {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: scene.width / 2
|
||||
spacing: 50
|
||||
columns: 2
|
||||
|
||||
Text {
|
||||
color: fineTuneView.textColor
|
||||
text: "Name:"
|
||||
|
||||
}
|
||||
InputField {
|
||||
text: echonestStation.name
|
||||
|
||||
onAccepted: {
|
||||
print("text changed!!!")
|
||||
echonestStation.name = text;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: tempoText
|
||||
text: "Tempo:"
|
||||
color: "white"
|
||||
}
|
||||
DoubleSlider {
|
||||
width: 500
|
||||
height: tempoText.height
|
||||
min: 0
|
||||
max: 500
|
||||
lowerSliderPos: echonestStation.minTempo
|
||||
upperSliderPos: echonestStation.maxTempo
|
||||
onValueChanged: echonestStation.setTempo( lowerSliderPos, upperSliderPos )
|
||||
}
|
||||
|
||||
Text {
|
||||
id: hotnessText
|
||||
text: "Hotness:"
|
||||
color: "white"
|
||||
}
|
||||
DoubleSlider {
|
||||
width: 500
|
||||
height: hotnessText.height
|
||||
min: 0
|
||||
max: 100
|
||||
minLabel: "Less"
|
||||
maxLabel: "More"
|
||||
showFloatingLabel: false
|
||||
lowerSliderPos: echonestStation.minHotttness * 100
|
||||
upperSliderPos: echonestStation.maxHotttness * 100
|
||||
onValueChanged: echonestStation.setHotttness( 1.0 * lowerSliderPos / 100, 1.0 * upperSliderPos / 100 )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Button {
|
||||
id: configureButton
|
||||
onClicked: fineTuneView.done();
|
||||
text: "configure"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
}
|
64
data/qml/stations/StationCreatorPage1.qml
Normal file
64
data/qml/stations/StationCreatorPage1.qml
Normal file
@@ -0,0 +1,64 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "../tomahawkimports"
|
||||
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property alias model: gridView.model
|
||||
property int spacing: 10
|
||||
|
||||
signal itemClicked(int index)
|
||||
|
||||
GridView {
|
||||
id: gridView
|
||||
anchors.centerIn: parent
|
||||
width: root.width * 9 / 10
|
||||
height: cellHeight
|
||||
|
||||
cellWidth: (width - 1) / 3
|
||||
cellHeight: cellWidth //* 10 / 16
|
||||
|
||||
delegate: Image {
|
||||
width: gridView.cellWidth - root.spacing
|
||||
height: gridView.cellHeight - root.spacing
|
||||
source: image
|
||||
smooth: true
|
||||
|
||||
Rectangle {
|
||||
id: textBackground
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
}
|
||||
height: parent.height / 5
|
||||
color: "black"
|
||||
opacity: .5
|
||||
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: textBackground
|
||||
text: label
|
||||
color: "white"
|
||||
font.bold: true
|
||||
}
|
||||
Rectangle {
|
||||
id: hoverShade
|
||||
anchors.fill: parent
|
||||
color: "white"
|
||||
opacity: mouseArea.containsMouse ? .2 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { easing.type: Easing.Linear; duration: 300 }
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: root.itemClicked(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
data/qml/stations/StationCreatorPage2.qml
Normal file
25
data/qml/stations/StationCreatorPage2.qml
Normal file
@@ -0,0 +1,25 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
import "../tomahawkimports"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property int margins: defaultFontHeight * 2
|
||||
property alias content: contentLoader.source
|
||||
|
||||
signal next()
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.margins
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: contentLoader.item
|
||||
|
||||
onDone: root.next()
|
||||
}
|
||||
|
||||
}
|
71
data/qml/tomahawkimports/ArtistView.qml
Normal file
71
data/qml/tomahawkimports/ArtistView.qml
Normal file
@@ -0,0 +1,71 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
ListView {
|
||||
id: root
|
||||
|
||||
property int delegateHeight: defaultFontHeight * 3
|
||||
|
||||
signal itemClicked(int index)
|
||||
|
||||
delegate: Item {
|
||||
width: parent.width
|
||||
height: root.delegateHeight
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
radius: defaultFontHeight / 2
|
||||
opacity: 0.5
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#00FFFFFF" }
|
||||
GradientStop { position: 1.0; color: "#AAFFFFFF" }
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hovered"; when: mouseArea.containsMouse
|
||||
PropertyChanges { target: background; opacity: 1 }
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "*"; to: "hovered"
|
||||
NumberAnimation { properties: "opacity"; duration: 100 }
|
||||
},
|
||||
Transition {
|
||||
from: "hovered"; to: "*"
|
||||
NumberAnimation { properties: "opacity"; duration: 600 }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
spacing: defaultFontHeight
|
||||
|
||||
CoverImage {
|
||||
id: coverImage
|
||||
height: parent.height
|
||||
width: height
|
||||
showLabels: false
|
||||
artworkId: model.coverID
|
||||
}
|
||||
Text {
|
||||
text: model.artistName
|
||||
color: "white"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - coverImage.width - parent.spacing
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: root.itemClicked(index)
|
||||
hoverEnabled: true
|
||||
}
|
||||
}
|
||||
}
|
52
data/qml/tomahawkimports/BusyIndicator.qml
Normal file
52
data/qml/tomahawkimports/BusyIndicator.qml
Normal file
@@ -0,0 +1,52 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Item {
|
||||
id: busyIndicator
|
||||
width: 100
|
||||
height: width
|
||||
property int barWidth: width / 10
|
||||
property int barHeight: height / 4
|
||||
property int count: 12
|
||||
property color color: "white"
|
||||
property int currentHighlight: 0
|
||||
property bool running: true
|
||||
property int interval: 200
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 500 }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: busyIndicator.count
|
||||
|
||||
|
||||
Item {
|
||||
height: parent.height
|
||||
width: busyIndicator.barWidth
|
||||
anchors.centerIn: parent
|
||||
Rectangle {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: busyIndicator.barHeight
|
||||
radius: width / 2
|
||||
|
||||
color: busyIndicator.color
|
||||
}
|
||||
rotation: 360 / busyIndicator.count * index
|
||||
opacity: 1 - ((index > busyIndicator.currentHighlight ? busyIndicator.currentHighlight + busyIndicator.count : busyIndicator.currentHighlight) - index) / busyIndicator.count
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: busyIndicator.interval }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: busyIndicator.interval
|
||||
running: busyIndicator.running
|
||||
repeat: true
|
||||
onTriggered: parent.currentHighlight = (parent.currentHighlight + 1) % busyIndicator.count
|
||||
}
|
||||
}
|
29
data/qml/tomahawkimports/Button.qml
Normal file
29
data/qml/tomahawkimports/Button.qml
Normal file
@@ -0,0 +1,29 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
color: buttonMouseArea.containsMouse ? "blue" : "gray"
|
||||
border.width: 2
|
||||
border.color: "white"
|
||||
radius: height/2
|
||||
height: buttonText.height * 1.2
|
||||
width: buttonText.width * 1.5
|
||||
|
||||
property alias text: buttonText.text
|
||||
property color textColor: "white"
|
||||
|
||||
signal clicked()
|
||||
|
||||
Text {
|
||||
id: buttonText
|
||||
anchors.centerIn: parent
|
||||
color: root.textColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: buttonMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: root.clicked();
|
||||
}
|
||||
}
|
137
data/qml/tomahawkimports/CoverFlip.qml
Normal file
137
data/qml/tomahawkimports/CoverFlip.qml
Normal file
@@ -0,0 +1,137 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
PathView {
|
||||
id: coverView
|
||||
|
||||
// The start coordinates for the covers
|
||||
// Default is left, centered in height
|
||||
property int pathStartX: 0
|
||||
property int pathStartY: height
|
||||
|
||||
// The size of the covers in the path
|
||||
property int coverSize: height
|
||||
|
||||
property color backgroundColor: "black"
|
||||
|
||||
// emitted when a cover is clicked
|
||||
signal itemClicked(int index)
|
||||
|
||||
// emitted when a cover is clicked
|
||||
signal itemPlayPauseClicked(int index)
|
||||
|
||||
preferredHighlightBegin: 0.2 // scene.width / 11000
|
||||
preferredHighlightEnd: preferredHighlightBegin
|
||||
pathItemCount: 5
|
||||
//highlightMoveDuration: 500
|
||||
|
||||
property bool itemHovered: false
|
||||
|
||||
delegate: Item {
|
||||
id: delegateItem
|
||||
height: coverView.coverSize
|
||||
width: coverView.coverSize
|
||||
|
||||
scale: PathView.itemScale
|
||||
// itemBrightness: PathView.itemBrightness - ((coverView.itemHovered && !coverDelegate.containsMouse) ? .4 : 0)
|
||||
property double itemBrightness: PathView.itemBrightness
|
||||
property double itemOpacity: PathView.itemOpacity
|
||||
property int _origZ
|
||||
|
||||
z: coverView.width - x
|
||||
|
||||
CoverImage {
|
||||
id: coverDelegate
|
||||
height: coverView.coverSize
|
||||
width: coverView.coverSize
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
backgroundColor: coverView.backgroundColor
|
||||
|
||||
showLabels: true
|
||||
showMirror: true
|
||||
artistName: model.artistName
|
||||
trackName: model.trackName
|
||||
artworkId: model.coverID
|
||||
showPlayButton: true
|
||||
currentlyPlaying: isPlaying
|
||||
smooth: true
|
||||
|
||||
// itemBrightness: PathView.itemBrightness - ((coverView.itemHovered && !coverDelegate.containsMouse) ? .4 : 0)
|
||||
itemBrightness: coverDelegate.containsMouse ? 1 : parent.itemBrightness * (coverView.itemHovered ? .5 : 1)
|
||||
opacity: parent.itemOpacity
|
||||
z: coverView.width - x
|
||||
|
||||
onPlayClicked: {
|
||||
console.log("***************")
|
||||
coverView.itemPlayPauseClicked(index)
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
coverView.itemClicked(index)
|
||||
}
|
||||
|
||||
onContainsMouseChanged: {
|
||||
if (containsMouse) {
|
||||
delegateItem._origZ = delegateItem.z;
|
||||
coverView.itemHovered = true
|
||||
} else {
|
||||
coverView.itemHovered = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
name: "hovered"; when: coverDelegate.containsMouse && !coverView.moving && index !== currentIndex
|
||||
PropertyChanges {
|
||||
target: delegateItem
|
||||
width: coverView.coverSize * 2
|
||||
z: delegateItem._origZ
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
NumberAnimation {
|
||||
properties: "width"
|
||||
duration: 300
|
||||
easing.type: Easing.InOutSine
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
path: Path {
|
||||
startX: coverView.pathStartX
|
||||
startY: coverView.pathStartY
|
||||
|
||||
PathAttribute { name: "itemOpacity"; value: 0 }
|
||||
PathAttribute { name: "itemBrightness"; value: 0 }
|
||||
PathAttribute { name: "itemScale"; value: 1.3 }
|
||||
|
||||
PathLine { x: coverView.width / 4; y: coverView.height / 4 * 3}
|
||||
PathPercent { value: 0.1 }
|
||||
PathAttribute { name: "itemOpacity"; value: 0 }
|
||||
PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
PathAttribute { name: "itemScale"; value: 1.0 }
|
||||
|
||||
PathLine { x: coverView.width / 2; y: coverView.height / 2}
|
||||
PathPercent { value: 0.2 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 1 }
|
||||
PathAttribute { name: "itemScale"; value: 0.5 }
|
||||
|
||||
PathLine { x: coverView.width; y: 0 }
|
||||
PathPercent { value: 1 }
|
||||
PathAttribute { name: "itemOpacity"; value: 1 }
|
||||
PathAttribute { name: "itemBrightness"; value: 0 }
|
||||
PathAttribute { name: "itemScale"; value: 0.1 }
|
||||
}
|
||||
|
||||
}
|
197
data/qml/tomahawkimports/CoverImage.qml
Normal file
197
data/qml/tomahawkimports/CoverImage.qml
Normal file
@@ -0,0 +1,197 @@
|
||||
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
|
||||
|
||||
// if this is true, the play button will be swapped by a pause button
|
||||
property bool currentlyPlaying: false
|
||||
|
||||
// Should the mirror be painted?
|
||||
property bool showMirror: false
|
||||
|
||||
// Labels & Cover
|
||||
property string artistName
|
||||
property string trackName
|
||||
property string artworkId
|
||||
|
||||
// The border color for the cover image
|
||||
property color borderColor: "black"
|
||||
// The border width for the cover image
|
||||
property int borderWidth: 2
|
||||
|
||||
// needed to adjust the shadow
|
||||
property color backgroundColor: "black"
|
||||
|
||||
// sets the brightness for the item and its mirror (1: brightest, 0: darkest)
|
||||
property double itemBrightness: 1
|
||||
property double mirrorBrightness: .5
|
||||
|
||||
// set this to true if you want to smoothly scale the cover (be aware of performance impacts)
|
||||
property bool smooth: false
|
||||
|
||||
// will be emitted when the on hower play button is clicked
|
||||
signal playClicked()
|
||||
// will be emitted when the cover is clicked
|
||||
signal clicked()
|
||||
// will be emitted when the cover is hovered by the mouse
|
||||
property alias containsMouse: mouseArea.containsMouse
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
print("Cover clicked");
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: itemShadow
|
||||
color: backgroundColor
|
||||
anchors.fill: parent
|
||||
|
||||
//opacity: 1 - itemBrightness
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { easing.type: Easing.Linear; duration: 300 }
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: coverImage
|
||||
|
||||
Item {
|
||||
property bool isMirror: false
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: "image://albumart/" + artworkId + (isMirror ? "-mirror" : "") + (showLabels ? "-labels" : "")
|
||||
smooth: root.smooth
|
||||
opacity: itemBrightness
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 300 }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: itemGlow
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: isMirror ? parent.height / 2 : 0
|
||||
|
||||
opacity: (mouseArea.containsMouse ? .2 : 0)
|
||||
|
||||
Gradient {
|
||||
id: glowGradient
|
||||
GradientStop { position: 0.0; color: "white" }
|
||||
GradientStop { position: 0.7; color: "white" }
|
||||
GradientStop { position: 0.8; color: "#00000000" }
|
||||
GradientStop { position: 1.0; color: "#00000000" }
|
||||
}
|
||||
Gradient {
|
||||
id: mirrorGlowGradient
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
GradientStop { position: 0.5; color: "#00000000" }
|
||||
GradientStop { position: 1.0; color: "#44FFFFFF" }
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "mirrored"; when: isMirror
|
||||
PropertyChanges {
|
||||
target: itemGlow
|
||||
gradient: mirrorGlowGradient
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "normal"; when: !isMirror
|
||||
PropertyChanges {
|
||||
target: itemGlow
|
||||
gradient: glowGradient
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { easing.type: Easing.Linear; duration: 300 }
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: trackText
|
||||
color: "white"
|
||||
font.bold: true
|
||||
text: trackName
|
||||
anchors { left: parent.left; right: parent.right; bottom: artistText.top }
|
||||
anchors.margins: 2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
opacity: showLabels ? itemBrightness * (isMirror ? 0.5 : 1): 0
|
||||
font.pixelSize: root.height / 15
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 300 }
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: artistText
|
||||
color: "white"
|
||||
font.bold: trackText.text.length == 0
|
||||
text: artistName
|
||||
anchors { left: parent.left; right: parent.right; bottom: parent.bottom }
|
||||
anchors.margins: root.height / 20
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
opacity: showLabels ? itemBrightness * (isMirror ? 0.5 : 1) : 0
|
||||
font.pixelSize: trackText.text.length == 0 ? root.height / 10 : root.height / 15
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 300 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loader {
|
||||
sourceComponent: coverImage
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: mirroredCover
|
||||
sourceComponent: parent.showMirror ? coverImage : undefined
|
||||
anchors.fill: parent
|
||||
onLoaded: {
|
||||
item.isMirror = true
|
||||
}
|
||||
transform : [
|
||||
Rotation {
|
||||
angle: 180; origin.y: root.height
|
||||
axis.x: 1; axis.y: 0; axis.z: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Image {
|
||||
id: playButton
|
||||
visible: showPlayButton ? (mouseArea.containsMouse || currentlyPlaying) : false
|
||||
source: currentlyPlaying ? "../../images/pause-rest.svg" : "../../images/play-rest.svg"
|
||||
anchors.centerIn: parent
|
||||
height: mirroredCover.height / 5
|
||||
width: height
|
||||
smooth: root.smooth
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
print("Play button clicked");
|
||||
root.playClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
151
data/qml/tomahawkimports/DoubleSlider.qml
Normal file
151
data/qml/tomahawkimports/DoubleSlider.qml
Normal file
@@ -0,0 +1,151 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 500
|
||||
height: 10
|
||||
|
||||
property int min: 0
|
||||
property int max: 100
|
||||
|
||||
/** The labels next to the slider
|
||||
* if empty, min and max values are used
|
||||
*/
|
||||
property string minLabel: ""
|
||||
property string maxLabel: ""
|
||||
|
||||
/** Should the floating label indicating the current position be shown? */
|
||||
property bool showFloatingLabel: true
|
||||
|
||||
property int lowerSliderPos: 25
|
||||
property int upperSliderPos: 75
|
||||
|
||||
signal valueChanged()
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
||||
Text {
|
||||
id: minText
|
||||
text: root.minLabel.length > 0 ? root.minLabel : min
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Item {
|
||||
id: sliderRect
|
||||
height: root.height
|
||||
width: parent.width - minText.width - maxText.width - parent.spacing * 2
|
||||
|
||||
function sliderPosToValue( sliderPos ) {
|
||||
var percent = sliderPos * 100 / (sliderRect.width - lowerSlider.width);
|
||||
return Math.floor(percent * (root.max - root.min) / 100) + root.min
|
||||
}
|
||||
|
||||
function valueToSloderPos( value ) {
|
||||
var percent = (value - root.min) * 100 / (root.max - root.min)
|
||||
return percent * (sliderRect.width - lowerSlider.width) / 100
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: sliderBase
|
||||
height: root.height / 5
|
||||
width: parent.width
|
||||
color: "white"
|
||||
radius: height / 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
}
|
||||
Rectangle {
|
||||
id: lowerSlider
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.top: root.top
|
||||
radius: height/2
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
x: sliderRect.valueToSloderPos(root.lowerSliderPos)
|
||||
|
||||
Rectangle {
|
||||
id: lowerFloatingRect
|
||||
color: "white"
|
||||
anchors.bottom: lowerSlider.top
|
||||
anchors.bottomMargin: 10
|
||||
visible: root.showFloatingLabel && lowerSliderMouseArea.pressed
|
||||
width: lowerFloatingText.width * 1.2
|
||||
height: lowerFloatingText.height + height * 1.2
|
||||
x: -(width - lowerSlider.width) / 2
|
||||
radius: height / 4
|
||||
|
||||
Text {
|
||||
id: lowerFloatingText
|
||||
anchors.centerIn: parent
|
||||
text: sliderRect.sliderPosToValue(lowerSlider.x)
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: lowerSliderMouseArea
|
||||
anchors.fill: lowerSlider
|
||||
drag.target: lowerSlider
|
||||
drag.axis: "XAxis"
|
||||
drag.minimumX: 0
|
||||
drag.maximumX: upperSlider.x - lowerSlider.width
|
||||
onReleased: {
|
||||
root.lowerSliderPos = sliderRect.sliderPosToValue( lowerSlider.x );
|
||||
root.valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: upperSlider
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.top: root.top
|
||||
radius: height/2
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
x: sliderRect.valueToSloderPos(root.upperSliderPos)
|
||||
Rectangle {
|
||||
id: upperFloatingRect
|
||||
color: "white"
|
||||
anchors.bottom: upperSlider.top
|
||||
anchors.bottomMargin: 10
|
||||
visible: root.showFloatingLabel && upperSliderMouseArea.pressed
|
||||
width: upperFloatingText.width * 1.2
|
||||
height: upperFloatingText.height + height * 1.2
|
||||
radius: height / 4
|
||||
x: -(width - upperSlider.width) / 2
|
||||
|
||||
Text {
|
||||
id: upperFloatingText
|
||||
anchors.centerIn: parent
|
||||
text: sliderRect.sliderPosToValue(upperSlider.x)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
MouseArea {
|
||||
id: upperSliderMouseArea
|
||||
anchors.fill: upperSlider
|
||||
onClicked: print("button pressed")
|
||||
drag.target: upperSlider
|
||||
drag.axis: "XAxis"
|
||||
drag.minimumX: lowerSlider.x + lowerSlider.width
|
||||
drag.maximumX: parent.width - upperSlider.width
|
||||
onReleased: {
|
||||
root.upperSliderPos = sliderRect.sliderPosToValue( upperSlider.x );
|
||||
root.valueChanged();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: maxText
|
||||
text: root.maxLabel.length > 0 ? root.maxLabel : max
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
199
data/qml/tomahawkimports/FlexibleHeader.qml
Normal file
199
data/qml/tomahawkimports/FlexibleHeader.qml
Normal file
@@ -0,0 +1,199 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
// The icon
|
||||
property alias icon: iconImage.source
|
||||
|
||||
// The title
|
||||
property alias title: titleItem.titleText
|
||||
|
||||
// The subtitle/description
|
||||
property alias subtitle: subtitleText.text
|
||||
|
||||
// The model for the ToggleViewButtons.
|
||||
// "modelData" role name holds the iconSource
|
||||
// => You can use a QStringList or StandardListModel here
|
||||
property alias buttonModel: toggleViewButtons.model
|
||||
|
||||
// The index of the currently selected item
|
||||
property alias currentButtonIndex: toggleViewButtons.currentIndex
|
||||
|
||||
// Should we show the searchfield?
|
||||
property bool showSearchField: true
|
||||
|
||||
// The SearchFields text
|
||||
property alias searchText: searchField.text
|
||||
|
||||
property bool showBackButton: false
|
||||
property bool showNextButton: false
|
||||
|
||||
property string backButtonText: "Back"
|
||||
property string nextButtonText: "Next"
|
||||
|
||||
// Layout spacing
|
||||
property int spacing: defaultFontHeight * 0.5
|
||||
|
||||
signal backPressed()
|
||||
signal nextPressed()
|
||||
signal savePressed()
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#615858" }
|
||||
GradientStop { position: 1.0; color: "#231F1F" }
|
||||
}
|
||||
|
||||
Row {
|
||||
id: leftRow
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: rightRow.left
|
||||
}
|
||||
|
||||
anchors.margins: root.spacing
|
||||
spacing: root.spacing
|
||||
|
||||
Image {
|
||||
id: iconImage
|
||||
height: parent.height * 0.8
|
||||
width: height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
}
|
||||
|
||||
Column {
|
||||
height: parent.height
|
||||
width: parent.width - iconImage.width - parent.spacing
|
||||
|
||||
Item {
|
||||
id: titleItem
|
||||
height: captionText1.height
|
||||
width: parent.width
|
||||
clip: true
|
||||
|
||||
property string titleText
|
||||
|
||||
onTitleTextChanged: {
|
||||
if(captionText1.text.length > 0) {
|
||||
captionText2.text = titleText;
|
||||
renewTitleAnimation.start();
|
||||
} else {
|
||||
captionText1.text = titleText;
|
||||
}
|
||||
}
|
||||
|
||||
ParallelAnimation {
|
||||
id: renewTitleAnimation
|
||||
property int duration: 500
|
||||
property variant easingType: Easing.OutBounce;
|
||||
|
||||
NumberAnimation { target: captionText2; property: "anchors.topMargin"; to: 0; duration: renewTitleAnimation.duration; easing.type: renewTitleAnimation.easingType }
|
||||
NumberAnimation { target: captionText1; property: "anchors.topMargin"; to: captionText1.height * 2; duration: renewTitleAnimation.duration; easing.type: renewTitleAnimation.easingType }
|
||||
|
||||
onCompleted: {
|
||||
captionText1.text = titleItem.titleText
|
||||
captionText2.anchors.topMargin = -captionText2.height * 2
|
||||
captionText1.anchors.topMargin = 0
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: captionText1
|
||||
color: "white"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
|
||||
font.pointSize: defaultFontSize * 1.5
|
||||
font.bold: true
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Text {
|
||||
id: captionText2
|
||||
color: "white"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: -height * 2
|
||||
font.pointSize: defaultFontSize * 1.5
|
||||
font.bold: true
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
}
|
||||
Text {
|
||||
id: subtitleText
|
||||
color: "white"
|
||||
font.pointSize: defaultFontSize * 1.2
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Row {
|
||||
id: rightRow
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: -backButton.width - root.spacing - nextButton.width
|
||||
bottom: parent.bottom
|
||||
margins: root.spacing
|
||||
}
|
||||
width: childrenRect.width
|
||||
spacing: root.spacing
|
||||
layoutDirection: Qt.RightToLeft
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "oneVisible"; when: root.showBackButton && !root.showNextButton
|
||||
PropertyChanges {
|
||||
target: rightRow
|
||||
anchors.rightMargin: -nextButton.width
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "bothVisible"; when: root.showBackButton && root.showNextButton
|
||||
PropertyChanges {
|
||||
target: rightRow
|
||||
anchors.rightMargin: root.spacing
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
Behavior on anchors.rightMargin {
|
||||
NumberAnimation { duration: 200 }
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: nextButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.nextButtonText
|
||||
onClicked: root.nextPressed();
|
||||
}
|
||||
PushButton {
|
||||
id: backButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.backButtonText
|
||||
onClicked: root.backPressed();
|
||||
}
|
||||
InputField {
|
||||
id: searchField
|
||||
visible: root.showSearchField
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
placeholderText: "Search..."
|
||||
showSearchIcon: true
|
||||
}
|
||||
ToggleViewButtons {
|
||||
id: toggleViewButtons
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: defaultFontHeight * 1.5
|
||||
}
|
||||
}
|
||||
}
|
7
data/qml/tomahawkimports/HeaderLabel.qml
Normal file
7
data/qml/tomahawkimports/HeaderLabel.qml
Normal file
@@ -0,0 +1,7 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Text {
|
||||
color: "white"
|
||||
font.pointSize: defaultFontSize + 5
|
||||
font.bold: true
|
||||
}
|
90
data/qml/tomahawkimports/InputField.qml
Normal file
90
data/qml/tomahawkimports/InputField.qml
Normal file
@@ -0,0 +1,90 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
color: "white"
|
||||
border.color: "black"
|
||||
border.width: defaultFontHeight * 0.1
|
||||
radius: defaultFontHeight * 0.25
|
||||
|
||||
height: textInput.height * 1.4
|
||||
width: 300
|
||||
|
||||
property bool showSearchIcon: false
|
||||
property string text: ""
|
||||
property string placeholderText: ""
|
||||
|
||||
property int spacing: defaultFontHeight * 0.2
|
||||
signal accepted( string text )
|
||||
|
||||
Image {
|
||||
id: searchIcon
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: root.spacing
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: parent.height * 0.6
|
||||
width: root.showSearchIcon ? height : 1
|
||||
opacity: root.showSearchIcon ? 1 : 0
|
||||
smooth: true
|
||||
source: "../../images/search-icon.svg"
|
||||
}
|
||||
|
||||
Item {
|
||||
id: textItem
|
||||
anchors.left: searchIcon.right
|
||||
anchors.leftMargin: root.spacing
|
||||
anchors.right: clearIcon.right
|
||||
anchors.rightMargin: root.spacing
|
||||
height: textInput.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
TextInput {
|
||||
id: textInput
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
text: root.text
|
||||
font.pointSize: defaultFontSize
|
||||
|
||||
onAccepted: root.accepted( text );
|
||||
onTextChanged: root.text = text;
|
||||
}
|
||||
Text {
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
text: root.text.length === 0 ? root.placeholderText : ""
|
||||
color: "lightgray"
|
||||
font.pointSize: defaultFontSize
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: clearIcon
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: root.spacing
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: parent.height * 0.8
|
||||
width: (root.showSearchIcon && root.text.length > 0) ? height : 1
|
||||
opacity: (root.showSearchIcon && root.text.length > 0) ? 1 : 0
|
||||
smooth: true
|
||||
source: "../../images/search-box-dismiss-x.svg"
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: textInput.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BorderImage {
|
||||
source: "../../images/inputfield-border.svg"
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.radius * 0.1
|
||||
clip: true
|
||||
border.left: defaultFontHeight/4; border.top: defaultFontHeight/4
|
||||
border.right: defaultFontHeight/4; border.bottom: defaultFontHeight/4
|
||||
}
|
||||
}
|
34
data/qml/tomahawkimports/PushButton.qml
Normal file
34
data/qml/tomahawkimports/PushButton.qml
Normal file
@@ -0,0 +1,34 @@
|
||||
import QtQuick 1.1
|
||||
//import tomahawk 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
height: buttonText.height * 1.4
|
||||
width: buttonText.width + (spacing * 2)
|
||||
radius: defaultFontHeight * 0.25
|
||||
border.width: defaultFontHeight * 0.05
|
||||
border.color: "#a7a7a7"
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: mouseArea.pressed ? "#040404" : "#fbfbfb" }
|
||||
GradientStop { position: 1.0; color: mouseArea.pressed ? "#8e8f8e" : "#787878" }
|
||||
}
|
||||
|
||||
property int spacing: defaultFontHeight * 0.5
|
||||
property alias text: buttonText.text
|
||||
|
||||
signal clicked()
|
||||
|
||||
Text {
|
||||
id: buttonText
|
||||
anchors.centerIn: root
|
||||
font.pointSize: defaultFontSize
|
||||
color: mouseArea.pressed ? "white" : "black"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
}
|
43
data/qml/tomahawkimports/RoundedButton.qml
Normal file
43
data/qml/tomahawkimports/RoundedButton.qml
Normal file
@@ -0,0 +1,43 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
border.width: 4
|
||||
border.color: enabled ? "white" : "grey"
|
||||
radius: height / 2
|
||||
color: (buttonMouseArea.containsMouse && enabled) ? "#22ffffff" : "black"
|
||||
opacity: hidden ? 0 : 1
|
||||
|
||||
height: defaultFontHeight * 2
|
||||
width: height
|
||||
|
||||
property string text
|
||||
property bool enabled: true
|
||||
property bool hidden: false
|
||||
|
||||
signal clicked()
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200 }
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation { duration: 200 }
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: parent.text
|
||||
color: root.border.color
|
||||
font.pixelSize: parent.height * .75
|
||||
font.bold: true
|
||||
}
|
||||
MouseArea {
|
||||
id: buttonMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: root.enabled
|
||||
onClicked: parent.clicked()
|
||||
}
|
||||
}
|
69
data/qml/tomahawkimports/ScrollBar.qml
Normal file
69
data/qml/tomahawkimports/ScrollBar.qml
Normal file
@@ -0,0 +1,69 @@
|
||||
import QtQuick 1.1
|
||||
|
||||
Item {
|
||||
id: scrollBar
|
||||
width: defaultFontHeight / 2
|
||||
|
||||
// the ListView where to attach this scrollbar
|
||||
property variant listView
|
||||
// the orientation of the scrollbar
|
||||
property variant orientation : Qt.Vertical
|
||||
|
||||
property int margin: defaultFontHeight * 0.25
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hidden"; when: !listView.moving
|
||||
PropertyChanges { target: scrollBar; opacity: 0 }
|
||||
},
|
||||
State {
|
||||
name: "visible"; when: listView.moving
|
||||
PropertyChanges { target: scrollBar; opacity: 1 }
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "hidden"
|
||||
to: "visible"
|
||||
NumberAnimation { properties: "opacity"; duration: 200 }
|
||||
},
|
||||
Transition {
|
||||
from: "visible"
|
||||
to: "hidden"
|
||||
NumberAnimation { properties: "opacity"; duration: 2000 }
|
||||
}
|
||||
]
|
||||
|
||||
anchors {
|
||||
left: orientation == Qt.Vertical ? listView.right : listView.left
|
||||
leftMargin: orientation == Qt.Vertical ? scrollBar.margin : 0
|
||||
top: orientation == Qt.Vertical ? listView.top : listView.bottom
|
||||
topMargin: orientation == Qt.Vertical ? 0 : scrollBar.margin
|
||||
bottom: orientation == Qt.Vertical ? listView.bottom : undefined
|
||||
right: orientation == Qt.Vertical ? undefined : listView.right
|
||||
}
|
||||
|
||||
// A light, semi-transparent background
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
|
||||
color: "white"
|
||||
opacity: 0.2
|
||||
clip: true
|
||||
// Size the bar to the required size, depending upon the orientation.
|
||||
Rectangle {
|
||||
property real position: orientation == Qt.Vertical ? (listView.contentY / listView.contentHeight) : (listView.contentX / listView.contentWidth)
|
||||
property real pageSize: orientation == Qt.Vertical ? (listView.height / listView.contentHeight) : (listView.width / listView.contentWidth)
|
||||
|
||||
x: orientation == Qt.Vertical ? 1 : (position * (scrollBar.width-2) + 1)
|
||||
y: orientation == Qt.Vertical ? (position * (scrollBar.height-2) + 1) : 1
|
||||
width: orientation == Qt.Vertical ? (parent.width-2) : (pageSize * (scrollBar.width-2))
|
||||
height: orientation == Qt.Vertical ? (pageSize * (scrollBar.height-2)) : (parent.height-2)
|
||||
radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
|
||||
color: "white"
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
80
data/qml/tomahawkimports/TagCloud.qml
Normal file
80
data/qml/tomahawkimports/TagCloud.qml
Normal file
@@ -0,0 +1,80 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
Item {
|
||||
id: tagCloud
|
||||
|
||||
property variant model: 10
|
||||
|
||||
signal tagClicked( string tag )
|
||||
|
||||
function randomNumber(min, max) {
|
||||
var date = new Date();
|
||||
return (max - min) * Math.random(date.getSeconds()) + min
|
||||
}
|
||||
|
||||
Flow {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
spacing: 3
|
||||
|
||||
Repeater {
|
||||
id: cloudRepeater
|
||||
model: tagCloud.model
|
||||
|
||||
delegate: Item {
|
||||
id: cloudItem
|
||||
width: delegateText.width * 1.1
|
||||
height: delegateText.height
|
||||
property double itemScale: Math.random() + .3
|
||||
scale: itemScale
|
||||
Text {
|
||||
id: delegateText
|
||||
color: "gray"
|
||||
//text: controlModel.controlAt( index ).summary
|
||||
text: modelData
|
||||
font.pointSize: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: tagCloud.randomNumber(0, 15)
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "hovered"; when: cloudItemMouseArea.containsMouse
|
||||
PropertyChanges {
|
||||
target: delegateText
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "*"
|
||||
to: "hovered"
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "hovered"
|
||||
to: "*"
|
||||
ColorAnimation {
|
||||
duration: 1000
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
MouseArea {
|
||||
id: cloudItemMouseArea
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: tagCloud.tagClicked( modelData )
|
||||
}
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation { easing: Easing.Linear; duration: 1000 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
data/qml/tomahawkimports/ToggleViewButtons.qml
Normal file
34
data/qml/tomahawkimports/ToggleViewButtons.qml
Normal file
@@ -0,0 +1,34 @@
|
||||
import QtQuick 1.1
|
||||
import tomahawk 1.0
|
||||
|
||||
Row {
|
||||
id: root
|
||||
width: repeater.width
|
||||
|
||||
property alias model: repeater.model
|
||||
property int currentIndex: 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
height: root.height
|
||||
width: count * height
|
||||
|
||||
|
||||
delegate: Image {
|
||||
height: repeater.height
|
||||
width: height
|
||||
|
||||
source: "../../images/view-toggle-" + (index === root.currentIndex ? "active-" : "inactive-" ) + (index === 0 ? "left" : ( index === repeater.count - 1 ? "right" : "centre" )) + ".svg"
|
||||
smooth: true
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: "../../images/" + modelData + (index === root.currentIndex ? "-active.svg" : "-inactive.svg")
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: root.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user