1
0
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:
Christian Muehlhaeuser
2013-05-18 22:53:18 +02:00
committed by Michael Zanetti
parent 09c272a07c
commit 17eeae9a8f
27 changed files with 1996 additions and 0 deletions

View 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
View 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
View 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
View 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
}
}
}

View 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
}
}
}
}

View 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);
}
}
}
}
}

View 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
}
}

View 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)
}
}
}
}

View 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()
}
}

View 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
}
}
}

View 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
}
}

View 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();
}
}

View 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 }
}
}

View 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();
}
}
}
}

View 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"
}
}
}

View 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
}
}
}

View File

@@ -0,0 +1,7 @@
import QtQuick 1.1
Text {
color: "white"
font.pointSize: defaultFontSize + 5
font.bold: true
}

View 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
}
}

View 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()
}
}

View 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()
}
}

View 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
}
}
}

View 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 }
}
}
}
}
}

View 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
}
}
}
}