From 6fd809bbdbfe628ef1e63b68665f374751838baf Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 16 Oct 2015 03:49:17 +0300 Subject: [PATCH] Display a playback page on the remote after selecting a file --- remote/qml/pages/BrowsePage.qml | 6 ++- remote/qml/pages/PlaybackPage.qml | 65 +++++++++++++++++++++++++++++ remote/remote.pro | 2 + remote/source/remote.cpp | 2 + remote/source/streamcontrolitem.cpp | 55 ++++++++++++++++++++++++ remote/source/streamcontrolitem.h | 37 ++++++++++++++++ remote/source/xinemacontrol.cpp | 15 +++++++ remote/source/xinemacontrol.h | 10 +++++ 8 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 remote/qml/pages/PlaybackPage.qml create mode 100644 remote/source/streamcontrolitem.cpp create mode 100644 remote/source/streamcontrolitem.h diff --git a/remote/qml/pages/BrowsePage.qml b/remote/qml/pages/BrowsePage.qml index 59ebff3..f853880 100644 --- a/remote/qml/pages/BrowsePage.qml +++ b/remote/qml/pages/BrowsePage.qml @@ -74,7 +74,11 @@ Page { text: modelData - onPressed: xinemaControl.play_file(browseDirectory.directory+"/"+modelData); + onPressed: + { + xinemaControl.play_file(browseDirectory.directory+"/"+modelData); + pageStack.replace("PlaybackPage.qml"); + } } } } diff --git a/remote/qml/pages/PlaybackPage.qml b/remote/qml/pages/PlaybackPage.qml new file mode 100644 index 0000000..4a487a4 --- /dev/null +++ b/remote/qml/pages/PlaybackPage.qml @@ -0,0 +1,65 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import fi.mikkosoft.xinema 0.1 + +Page +{ + id: page + + Column + { + width: parent.width + spacing: Theme.paddingLarge + + PageHeader + { + title: qsTr("Playback") + } + + Label + { + text: streamControl.title + } + + Slider + { + id: slider + width: parent.width + minimumValue: 0.0 + maximumValue: Math.max(streamControl.duration, 1.0) + valueText: + { + var secs = Math.round(value); + var mins = Math.floor(secs/60); + secs %= 60; + var hours = Math.floor(mins/60); + mins %= 60; + + var str = ""; + if(hours>0) + { + str = hours+":"; + if(mins<10) + str += "0"; + } + + str += mins+":"; + if(secs<10) + str += "0"; + + return str+secs; + } + } + } + + StreamControl + { + id: streamControl + control: xinemaControl + onPositionChanged: + { + if(!slider.down) + slider.value = streamControl.position + } + } +} diff --git a/remote/remote.pro b/remote/remote.pro index ee41215..55e4e03 100644 --- a/remote/remote.pro +++ b/remote/remote.pro @@ -7,12 +7,14 @@ SOURCES += source/browsedirectoryitem.cpp \ source/discovery.cpp \ source/discoveryitem.cpp \ source/remote.cpp \ + source/streamcontrolitem.cpp \ source/xinemacontrol.cpp \ source/xinemacontrolitem.cpp HEADERS += source/browsedirectoryitem.h \ source/discovery.h \ source/discoveryitem.h \ + source/streamcontrolitem.h \ source/xinemacontrol.h \ source/xinemacontrolitem.h diff --git a/remote/source/remote.cpp b/remote/source/remote.cpp index e405626..48ef228 100644 --- a/remote/source/remote.cpp +++ b/remote/source/remote.cpp @@ -3,6 +3,7 @@ #include #include "browsedirectoryitem.h" #include "discoveryitem.h" +#include "streamcontrolitem.h" #include "xinemacontrolitem.h" int main(int argc, char **argv) @@ -10,6 +11,7 @@ int main(int argc, char **argv) QGuiApplication *app = SailfishApp::application(argc, argv); qmlRegisterType("fi.mikkosoft.xinema", 0, 1, "BrowseDirectory"); qmlRegisterType("fi.mikkosoft.xinema", 0, 1, "Discovery"); + qmlRegisterType("fi.mikkosoft.xinema", 0, 1, "StreamControl"); qmlRegisterType("fi.mikkosoft.xinema", 0, 1, "XinemaControl"); QQuickView *view = SailfishApp::createView(); view->setSource(SailfishApp::pathTo("qml/main.qml")); diff --git a/remote/source/streamcontrolitem.cpp b/remote/source/streamcontrolitem.cpp new file mode 100644 index 0000000..a225d52 --- /dev/null +++ b/remote/source/streamcontrolitem.cpp @@ -0,0 +1,55 @@ +#include "streamcontrolitem.h" +#include "xinemacontrolitem.h" + +StreamControlItem::StreamControlItem(): + control(0) +{ +} + +void StreamControlItem::set_control(XinemaControlItem *c) +{ + if(control) + disconnect(control, 0, this, 0); + + control = c; + if(control) + { + XinemaControl &xc = control->get_control(); + connect(&xc, &XinemaControl::title_changed, this, &StreamControlItem::title_changed); + connect(&xc, &XinemaControl::duration_changed, this, &StreamControlItem::duration_changed); + connect(&xc, &XinemaControl::position_changed, this, &StreamControlItem::position_changed); + } + + emit control_changed(); + + if(control) + { + emit title_changed(); + emit duration_changed(); + emit position_changed(); + } +} + +QString StreamControlItem::get_title() const +{ + if(!control) + return QString(); + + return control->get_control().get_title(); +} + +float StreamControlItem::get_duration() const +{ + if(!control) + return 0; + + return control->get_control().get_duration(); +} + +float StreamControlItem::get_position() const +{ + if(!control) + return 0; + + return control->get_control().get_position(); +} diff --git a/remote/source/streamcontrolitem.h b/remote/source/streamcontrolitem.h new file mode 100644 index 0000000..5b9b2bc --- /dev/null +++ b/remote/source/streamcontrolitem.h @@ -0,0 +1,37 @@ +#ifndef STREAMCONTROLITEM_H_ +#define STREAMCONTROLITEM_H_ + +#include + +class XinemaControlItem; + +class StreamControlItem: public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(XinemaControlItem *control READ get_control WRITE set_control NOTIFY control_changed) + Q_PROPERTY(QString title READ get_title NOTIFY title_changed) + Q_PROPERTY(float duration READ get_duration NOTIFY duration_changed) + Q_PROPERTY(float position READ get_position NOTIFY position_changed) + +private: + XinemaControlItem *control; + +public: + StreamControlItem(); + + void set_control(XinemaControlItem *); + XinemaControlItem *get_control() const { return control; } + + QString get_title() const; + float get_duration() const; + float get_position() const; + +signals: + void control_changed(); + void title_changed(); + void duration_changed(); + void position_changed(); +}; + +#endif diff --git a/remote/source/xinemacontrol.cpp b/remote/source/xinemacontrol.cpp index 76108b9..63399a6 100644 --- a/remote/source/xinemacontrol.cpp +++ b/remote/source/xinemacontrol.cpp @@ -77,4 +77,19 @@ void XinemaControl::process_reply(const QString &reply) emit subdirectory_added(args); else if(keyword=="file") emit file_added(args); + else if(keyword=="title") + { + title = args; + emit title_changed(title); + } + else if(keyword=="duration") + { + duration = args.toFloat(); + emit duration_changed(duration); + } + else if(keyword=="position") + { + position = args.toFloat(); + emit position_changed(position); + } } diff --git a/remote/source/xinemacontrol.h b/remote/source/xinemacontrol.h index 5dd5e27..dc7ad8f 100644 --- a/remote/source/xinemacontrol.h +++ b/remote/source/xinemacontrol.h @@ -11,6 +11,9 @@ class XinemaControl: public QObject private: QTcpSocket socket; QByteArray buffer; + QString title; + float duration; + float position; public: XinemaControl(); @@ -21,12 +24,19 @@ public: void list_directory(const QString &); void play_file(const QString &); + const QString &get_title() const { return title; } + float get_duration() const { return duration; } + float get_position() const { return position; } + signals: void connected(); void disconnected(); void directory_started(const QString &); void file_added(const QString &); void subdirectory_added(const QString &); + void title_changed(const QString &); + void duration_changed(float); + void position_changed(float); private: void send_request(const QString &); -- 2.45.2