mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-18 03:41:27 +02:00
* Imported QML resources.
This commit is contained in:
committed by
Michael Zanetti
parent
09c272a07c
commit
17eeae9a8f
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