diff options
24 files changed, 431 insertions, 96 deletions
diff --git a/port-files/FreeBSD/x11/lumina-core/pkg-plist b/port-files/FreeBSD/x11/lumina-core/pkg-plist index d95c8baf..a4bbbf8d 100644 --- a/port-files/FreeBSD/x11/lumina-core/pkg-plist +++ b/port-files/FreeBSD/x11/lumina-core/pkg-plist @@ -1649,6 +1649,8 @@ share/lthemeengine/colors/waves.conf share/lthemeengine/desktop_qss/DarkGlass.qss share/lthemeengine/desktop_qss/Glass.qss share/lthemeengine/qss/scrollbar-simple.qss +share/lthemeengine/qss/sliders-simple.qss +share/lthemeengine/qss/tooltip-simple.qss share/lumina-desktop/Login.ogg share/lumina-desktop/Logout.ogg share/lumina-desktop/colors/Black.qss.colors diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp new file mode 100644 index 00000000..895a3a32 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -0,0 +1,58 @@ +#include "LVideoSurface.h" +#include <QDebug> + +LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { + frameImage = QPixmap(); +} + +bool LVideoSurface::present(const QVideoFrame &frame) { + if(!frameImage.isNull()) { + emit frameReceived(frameImage); + return true; + } + + if(frame.isValid()) { + qDebug() << "Recording Frame" << frame.pixelFormat(); + QVideoFrame icon(frame); + icon.map(QAbstractVideoBuffer::ReadOnly); + QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); + + if(frameImage.isNull()) + frameImage = QPixmap::fromImage(img.copy(img.rect())); + + icon.unmap(); + emit frameReceived(frameImage); + return true; + } + return false; +} + +QList<QVideoFrame::PixelFormat> LVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const { + Q_UNUSED(type); + return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; +} + +/*bool VideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + return imageFormat != QImage::Format_Invalid && !size.isEmpty() && format.handleType() == QAbstractVideoBuffer::NoHandle; +} + +void VideoSurface::stop() { + QAbstractVideoSurface::stop(); +} + +bool VideoSurface::start(const QVideoSurfaceFormat &format) { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) { + this->imageFormat = imageFormat; + QAbstractVideoSurface::start(format); + return true; + } else { + return false; + } +}*/ diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h new file mode 100644 index 00000000..42a140d9 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -0,0 +1,21 @@ +#include <QAbstractVideoSurface> +#include <QVideoSurfaceFormat> +#include <QPixmap> +#include <QDebug> + +class LVideoSurface : public QAbstractVideoSurface { + Q_OBJECT + + public: + LVideoSurface(QObject *parent=0); + virtual bool present(const QVideoFrame&); + virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; + /*virtual QList<QVidebool isFormatSupported(const QVideoSurfaceFormat &format) const; + bool start(const QVideoSurfaceFormat &format); + void stop();*/ + signals: + void frameReceived(QPixmap); + private: + QPixmap frameImage; + //QImage::Format imageFormat; +}; diff --git a/src-qt5/core/libLumina/LVideoSurface.pri b/src-qt5/core/libLumina/LVideoSurface.pri new file mode 100644 index 00000000..469b8c93 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.pri @@ -0,0 +1,9 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoSurface.h +SOURCES *= $${PWD}/LVideoSurface.cpp + +INCLUDEPATH *= ${PWD} + +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss index 265ff20c..d0c9b448 100644 --- a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss +++ b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss @@ -11,7 +11,7 @@ QScrollBar:vertical{ QScrollBar::handle{ background: palette(base); border: 1px solid transparent; - border-radius: 7px; + border-radius: 1px; } QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{ background: palette(highlight); diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss new file mode 100644 index 00000000..e8311e92 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss @@ -0,0 +1,70 @@ +/* SLIDERS */ +QSlider::groove:horizontal { +border: 1px solid transparent; +background: palette(alternate-window); +height: 10px; +border-radius: 3px; +} +QSlider::groove:vertical { +border: 1px solid transparent; +background: palette(alternate-window); +width: 10px; +border-radius: 3px; +} +QSlider::sub-page:horizontal { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::sub-page:vertical { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::add-page:horizontal{ +background: palette(alternate-window); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::add-page:vertical{ +background: palette(alternate-window); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::handle:horizontal{ +background: palette(mid); +border: 1px solid palette(mid); +width: 1em; +border-radius: 1px; +} +QSlider::handle:vertical{ +background: palette(mid); +border: 1px solid palette(mid); +height: 1em; +border-radius: 1px; +} +QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{ +border: 1px solid palette(highlight); +background: palette(highlight); +} + +QSlider::sub-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::add-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::handle:horizontal:disabled { +background: palette(alternate-window); +border: 1px solid palette(highlight); +} diff --git a/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss new file mode 100644 index 00000000..9bee3e08 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss @@ -0,0 +1,7 @@ +QToolTip{ + background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 palette(window), stop: 1 palette(alternate-window)); + border-radius: 3px; + border: 1px solid palette(highlight); + padding: 1px; + color: palette(text); +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp index d4544c7b..28a5e558 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp @@ -55,7 +55,7 @@ void MainWindow::on_buttonBox_clicked(QAbstractButton *button){ if(p) { p->writeSettings(); } } } - if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel){ + if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel || id== QDialogButtonBox::Close){ close(); qApp->quit(); } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui index dd676c37..0dc3245d 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui @@ -293,7 +293,7 @@ Styles</string> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set> </property> </widget> </item> diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp index cd88fb56..6377016c 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp @@ -31,6 +31,7 @@ QSSPage::QSSPage(QWidget *parent, bool desktop) : TabPage(parent), m_ui(new Ui:: m_ui->removeButton->setIcon(QIcon::fromTheme("edit-delete")); m_ui->tool_enable->setEnabled(false); m_ui->tool_disable->setEnabled(false); + m_ui->copyButton->setEnabled(false); } QSSPage::~QSSPage(){ @@ -56,6 +57,7 @@ void QSSPage::on_qssListWidget_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_disable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -76,6 +78,7 @@ void QSSPage::on_list_disabled_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_enable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -127,6 +130,36 @@ void QSSPage::on_editButton_clicked(){ } } +void QSSPage::on_copyButton_clicked(){ + QListWidgetItem *sel = currentSelection(); + if(sel==0){ return; } + QString name = QInputDialog::getText(this, tr("Enter Style Sheet Name"), tr("File name:"), QLineEdit::Normal, sel->text().section(".qss",0,0)+"_copy"); + if(name.isEmpty()){ return; } + if(!name.endsWith(".qss", Qt::CaseInsensitive)){ name.append(".qss"); } + QString filePath; + if(desktop_qss){ filePath = lthemeengine::userDesktopStyleSheetPath() + name; } + else{ filePath = lthemeengine::userStyleSheetPath() + name; } + if(QFile::exists(filePath)){ + QMessageBox::warning(this, tr("Error"), tr("The file \"%1\" already exists").arg(filePath)); + return; + } + // Make sure the directory exists + QString dir = filePath.section("/",0,-2); + if(!QFile::exists(dir)){ + QDir D(dir); + D.mkpath(dir); + } + //Copy the file over + QFile::copy(sel->data(QSS_FULL_PATH_ROLE).toString(), filePath); + //creating item + QFileInfo info(filePath); + QListWidgetItem *item = new QListWidgetItem(info.fileName(), m_ui->list_disabled); + item->setToolTip(info.filePath()); + item->setData(QSS_FULL_PATH_ROLE, info.filePath()); + item->setData(QSS_WRITABLE_ROLE, info.isWritable()); + m_ui->list_disabled->setCurrentRow(m_ui->list_disabled->count()-1); +} + void QSSPage::on_removeButton_clicked(){ QListWidgetItem *item = currentSelection(); if(!item){ return; } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h index 5b0025c5..07df4ac2 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h @@ -24,6 +24,7 @@ private slots: void on_qssListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_list_disabled_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_createButton_clicked(); + void on_copyButton_clicked(); void on_editButton_clicked(); void on_removeButton_clicked(); void on_renameButton_clicked(); diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui index f9a980f3..def99dd0 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui @@ -63,7 +63,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -168,7 +168,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -222,16 +222,41 @@ <property name="enabled"> <bool>true</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Create</string> </property> </widget> </item> <item> + <widget class="QToolButton" name="copyButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Copy</string> + </property> + </widget> + </item> + <item> <widget class="QPushButton" name="editButton"> <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Edit</string> </property> @@ -242,6 +267,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Rename</string> </property> @@ -252,6 +283,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Remove</string> </property> diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp index d82f09ce..40d2d544 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp @@ -8,6 +8,7 @@ #include "MainUI.h" #include "ui_MainUI.h" +#include <QVideoFrame> #include <QFileDialog> #include <QMessageBox> @@ -22,11 +23,19 @@ MainUI::MainUI() : QDialog(), ui(new Ui::MainUI){ terminate_thread = false; UpdateIcons(); //Set all the icons in the dialog SetupConnections(); + player = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + surface = new LVideoSurface(this); + player->setVideoOutput(surface); + player->setMuted(true); + connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); + connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); INFO = 0; } MainUI::~MainUI(){ terminate_thread = true; + surface->deleteLater(); + player->deleteLater(); this->close(); } @@ -86,6 +95,11 @@ void MainUI::LoadFile(QString path, QString type){ ui->label_file_icon->setPixmap( pix.scaledToHeight(64) ); ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" ); //qDebug() << " - done with image"; + }else if(INFO->isVideo()){ + player->setMedia(QUrl("file://"+INFO->absoluteFilePath())); + player->play(); + player->pause(); + //Pixmap set when video is loaded in stopVideo }else{ ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) ); } @@ -296,6 +310,18 @@ void MainUI::getXdgCommand(QString prev){ xdgvaluechanged(); } +void MainUI::stopVideo(QPixmap img) { + ui->label_file_icon->setPixmap( img.scaledToHeight(64) ); + player->pause(); +} + +void MainUI::setDuration(QMediaPlayer::MediaStatus status) { + if(status == QMediaPlayer::BufferedMedia) { + player->setPosition(player->duration() / 2); + player->play(); + } +} + void MainUI::on_tool_xdg_getDir_clicked(){ //Find a directory QString dir = ui->line_xdg_wdir->text(); diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h index cbe23d9e..5ce7b01a 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h @@ -14,11 +14,11 @@ #define _LUMINA_FILE_INFO_MAIN_UI_H #include <QDialog> - +#include <QMediaPlayer> #include <LuminaXDG.h> +#include <LVideoSurface.h> -namespace Ui{ - class MainUI; +namespace Ui{ class MainUI; }; class MainUI : public QDialog{ @@ -35,6 +35,9 @@ public slots: private: Ui::MainUI *ui; LFileInfo *INFO; + LVideoSurface *surface; + QMediaPlayer *player; + bool flag; bool canwrite; bool terminate_thread; //flag for terminating the GetDirSize task @@ -51,6 +54,8 @@ private slots: //UI Buttons void on_push_close_clicked(); void on_push_save_clicked(); + void stopVideo(QPixmap); + void setDuration(QMediaPlayer::MediaStatus); void getXdgCommand(QString prev = ""); //void on_tool_xdg_getCommand_clicked(QString prev = ""); void on_tool_xdg_getDir_clicked(); diff --git a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro index bbaf842e..b53d8cba 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro +++ b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro @@ -1,7 +1,7 @@ include("$${PWD}/../../OS-detect.pri") QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent multimedia TARGET = lumina-fileinfo @@ -13,6 +13,7 @@ target.path = $${L_BINDIR} include(../../core/libLumina/LUtils.pri) #includes LUtils include(../../core/libLumina/LuminaXDG.pri) #include(../../core/libLumina/LuminaSingleApplication.pri) +include(../../core/libLumina/LVideoSurface.pri) include(../../core/libLumina/LuminaThemes.pri) SOURCES += main.cpp\ diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp index f2bdc178..211ef8d0 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp +++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp @@ -16,10 +16,13 @@ Browser::Browser(QObject *parent) : QObject(parent){ watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(QString)) ); - connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) ); + connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) ); showHidden = false; showThumbs = false; imageFormats = LUtils::imageExtensions(false); //lowercase suffixes + videoFormats = LUtils::videoExtensions(); //lowercase suffixes + //connect(surface, SIGNAL(frameReceived(QImage)), this, SLOT(captureFrame(QImage))); + //connect(player, &QMediaPlayer::mediaStatusChanged, this, [&]{ stopVideo(player, player->mediaStatus()); }); connect(this, SIGNAL(threadDone(QString, QImage)), this, SLOT(futureFinished(QString, QImage))); //will always be between different threads } @@ -60,21 +63,20 @@ void Browser::loadItem(QString info, Browser *obj){ file.close(); pix.loadFromData(bytes); if(pix.width() > 256 || pix.height() > 256 ){ - pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::SmoothTransformation); + pix = pix.scaled(256,256, Qt::KeepAspectRatio); } } } - - //qDebug() << " - done with item:" << info; + qDebug() << " - done with item:" << info; obj->emit threadDone(info, pix); } -QIcon Browser::loadIcon(QString icon){ +QIcon* Browser::loadIcon(QString icon){ if(!mimeIcons.contains(icon)){ mimeIcons.insert(icon, LXDG::findIcon(icon, "unknown")); } - return mimeIcons[icon]; + return &mimeIcons[icon]; } @@ -92,24 +94,58 @@ void Browser::dirChanged(QString dir){ else if(dir.startsWith(currentDir)){ QtConcurrent::run(this, &Browser::loadItem, dir, this ); } } +void Browser::stopVideo(QMediaPlayer *player, QMediaPlayer::MediaStatus status) { + //qDebug() << status; + if(status == QMediaPlayer::BufferedMedia) { + qDebug() << "stoppingVideo" << player << player->currentMedia().canonicalUrl(); + player->setPosition(player->duration() / 2); + player->pause(); + } +} + +void Browser::captureFrame(QPixmap pix, QIcon *ico) { + qDebug() << "grabbing frame"; + *ico = pix.scaledToHeight(64); + emit frameChanged(); +} + void Browser::futureFinished(QString name, QImage icon){ //Note: this will be called once for every item that loads - QIcon ico; - //LFileInfo info(name); + QIcon *ico = new QIcon(); LFileInfo *info = new LFileInfo(name); if(!icon.isNull() && showThumbs){ - //qDebug() << " -- Data:"; QPixmap pix = QPixmap::fromImage(icon); - ico.addPixmap(pix); - //}else if(info->isDir()){ - //qDebug() << " -- Folder:"; - //ico = loadIcon("folder"); + ico->addPixmap(pix); } - if(ico.isNull()){ - //qDebug() << " -- MimeType:" << info.fileName() << info.mimetype(); - ico = loadIcon(info->iconfile()); + if(ico->isNull()){ + if(videoFormats.contains(name.section(".",-1).toLower())) { + qDebug() << "Loading Video for" << name; + //qDebug() << "VIDEO" << info; + QMediaPlayer *player = new QMediaPlayer(0, QMediaPlayer::VideoSurface); + qDebug() << " - created player"; + LVideoSurface *surface = new LVideoSurface(); + qDebug() << " - Create objects"; + connect(surface, &LVideoSurface::frameReceived, this, [&] (QPixmap pix) { captureFrame(pix, ico); }); + connect(player, &QMediaPlayer::mediaStatusChanged, this, [&]{ stopVideo(player, player->mediaStatus()); }); + player->setVideoOutput(surface); + player->setMuted(true); + player->setMedia(QUrl("file://"+info->absoluteFilePath())); + player->play(); + player->pause(); + + QEventLoop loop; + connect(this, SIGNAL(frameChanged()), &loop, SLOT(quit())); + loop.exec(); + + ico->addPixmap(videoFrame); + //ico = loadIcon(info->iconfile()); + delete player; + delete surface; + }else { + ico = loadIcon(info->iconfile()); + } } - this->emit itemDataAvailable( ico, info); + this->emit itemDataAvailable( *ico, info); //qDebug() << " -- done:" << name; } diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.h b/src-qt5/desktop-utils/lumina-fm/Browser.h index 94f6ba3f..379753ab 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.h +++ b/src-qt5/desktop-utils/lumina-fm/Browser.h @@ -15,6 +15,8 @@ #include <QIcon> //#include <QFutureWatcher> +#include <QMediaPlayer> +#include <LVideoSurface.h> #include <LuminaXDG.h> /*class FileItem{ public: @@ -43,22 +45,23 @@ public: private: QString currentDir; QFileSystemWatcher *watcher; + QPixmap videoFrame; bool showHidden, showThumbs; - QStringList imageFormats, oldFiles; + QStringList imageFormats, videoFormats, oldFiles; QHash<QString, QIcon> mimeIcons; //cache for quickly re-using QIcons void loadItem(QString info, Browser *obj); //this is the main loader class - multiple instances each run in a separate thread - QIcon loadIcon(QString icon); //simplification for using/populating the mimIcons cache + QIcon* loadIcon(QString icon); //simplification for using/populating the mimIcons cache private slots: void fileChanged(QString); //tied into the watcher - for file change notifications void dirChanged(QString); // tied into the watcher - for new/removed files in the current dir - + void captureFrame(QPixmap, QIcon*); + void stopVideo(QMediaPlayer*, QMediaPlayer::MediaStatus); void futureFinished(QString, QImage); public slots: void loadDirectory(QString dir = ""); - signals: //Main Signals void itemRemoved(QString item); //emitted if a file was removed from the underlying @@ -70,6 +73,8 @@ signals: //Internal signal for the alternate threads void threadDone(QString, QImage); + + void frameChanged(); }; #endif diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro index 6c340e14..6cb4a537 100644 --- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro +++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro @@ -15,6 +15,7 @@ include(../../core/libLumina/LuminaXDG.pri) include(../../core/libLumina/LuminaSingleApplication.pri) include(../../core/libLumina/LuminaThemes.pri) include(../../core/libLumina/ExternalProcess.pri) +include(../../core/libLumina/LVideoSurface.pri) SOURCES += main.cpp \ MainUI.cpp \ diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp index ee7fb9e3..d0ecdecf 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp +++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp @@ -1,33 +1,59 @@ -#include "vidnail.h" -vidnail::vidnail(QWidget *parent) : QMainWindow(parent), mplayer(parent, QMediaPlayer::VideoSurface){ //there is no UI, so not sure how to alter the constructor +#ifndef VIDNAIL_H +#define VIDNAIL_H + +extern "C" { +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> } -vidnail::~vidnail() -{ +class VidNail; -vidnail::grabvideothumbnail(){ - vsurface = new QAbstractVideoSurface(); - mplayer.setVideoOutput(vsurface); - mplayer.setMedia($file); // video file to get thumbnail of - imageCaptured = QPixmap(); - mplayer.setPosition(2000); // time in milliseconds - mplayer.setMuted(true); // just to make sure no sound is emited - mplayer.play(); +struct vFrame { + vFrame() : *width(0), *height(0) {} + vFrame(int *width, int *height : width(width), height(height) {} + int *width; + int *height; +}; - currentFrame = frame; - const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); - const QSize size = format.frameSize(); +public: - this->imageFormat = imageFormat; - QAbstractVideoSurface::start(format); - QImage image( currentFrame.bits(), currentFrame.width(), currentFrame.height(), currentFrame.bytesPerLine(), imageFormat); - imageCaptured = QPixmap::fromImage(image.copy(image.rect())); + QString getCodec(); + void skipTo(int timeInSeconds); + void readVideoFrame(); + void getScaledVideoFrame(int scaledSize, vFrame& vFrame); -// Now do scaling with regular thumbnail process to make proper size + int getWidth(); + int getHeight(); + int getLength(); + + void makeThumbnail(const QString& videoFile, QImage &image); + void setThumbnailSize(int size); + void setPercentage(int percent); + void setTime(const QString& Time); + + void writeVidNail(vFrame& frame, QImage& image); + + + private: + bool readVideoPacket(); + bool getVideoPacket(); + void scaleVideo(int scaledSize, int& scaledWidth, int& scaledHeight); + void createVFrame(AVFrame *vFrame, quint8 *frameBuffer, int width, int height); + void calculateDimensions(int size); + void generateThumbnail(const QString& videoFile, ImageWriter& imageWriter, QImage& image); + QString getMimeType(const QString& videoFile); + QString getExtension(const QString& videoFilename); - mplayer.stop(); - vsurface.stop(); -} + private: + int videoStream; + AVFormatContext *inputVideoFormatContext; + AVCodecContext *inputvideoCodecContext; + AVCodec *inputVideoCodec; + AVStream *inputVideoStream; + AVFrame *inputVideoFrame; + quint8 *inputFrameBuffer; + AVPacket *videoPacket; +#endif // VIDNAIL_H diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h index ad565749..e13894e1 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h @@ -1,25 +1,13 @@ -#ifndef VIDNAIL_H -#define VIDNAIL_H - -#include <QMediaPlayer> -#include <QtMultimediaWidgets> -#include "videowidgetsurface.h" -#include <QPixmap> -#include <QAbstractVideoSurface> -#include <QImage> -#include <QRect> -#include <QVideoFrame> - -public: - - void grabvideothumbnail(); - -private: - - QAbstractVideoSurface *vsurface; - QImage::Format imageFormat; - QPixmap imageCaptured; - - -#endif // VIDNAIL_H - +//=========================================== +// Lumina-DE source code +// Copyright (c) 2017, q5sys +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "vidnail.h" + +VidNail::VidNail(QObject *parent) : QObject(parent){ +} + +VidNail::~VidNail(){ +} diff --git a/src-qt5/src-glwidgets/gltest/colorchange.h b/src-qt5/src-glwidgets/gltest/colorchange.h index d62fcd5c..aad01f05 100644 --- a/src-qt5/src-glwidgets/gltest/colorchange.h +++ b/src-qt5/src-glwidgets/gltest/colorchange.h @@ -13,14 +13,9 @@ private: public slots: void toggle(){ - static int current = 0; - if(current==0){ - base->setBackgroundColor(QColor(Qt::red)); - }else{ - base->setBackgroundColor(QColor(Qt::blue)); - current = -1; - } - current++; + static bool current = false; + base->setBackgroundColor( current ? QColor(Qt::blue) : QColor(Qt::red)); + current = !current; } public: diff --git a/src-qt5/src-glwidgets/gltest/main.cpp b/src-qt5/src-glwidgets/gltest/main.cpp index b303cb6b..efcebea1 100644 --- a/src-qt5/src-glwidgets/gltest/main.cpp +++ b/src-qt5/src-glwidgets/gltest/main.cpp @@ -10,14 +10,14 @@ int main(int argc, char** argv){ - QSurfaceFormat fmt; + QSurfaceFormat fmt; fmt.setRenderableType(QSurfaceFormat::OpenGL); //OpenGL, OpenGLES, OpenVG fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - QSurfaceFormat::setDefaultFormat(fmt); + QSurfaceFormat::setDefaultFormat(fmt); QApplication A(argc,argv); - qDebug() << "Creating base widget"; + qDebug() << "Creating base widget"; GLW_Base base; qDebug() << "Resize base widget"; base.resize(1024,768); @@ -29,7 +29,7 @@ int main(int argc, char** argv){ GLW_Widget wgt(&base); wgt.setGLBase(&base); wgt.setGeometry(75,50,50,50); - QPropertyAnimation anim(&wgt); + QPropertyAnimation anim(&wgt); anim.setTargetObject(&wgt); anim.setPropertyName("geometry"); //anim.setStartValue(QRect(-50,-50,50,50)); @@ -46,6 +46,7 @@ int main(int argc, char** argv){ colorchange CC(&base); qDebug() << "Start Event loop"; base.show(); - A.exec(); - qDebug() << " - Finished"; + int ret = A.exec(); + qDebug() << " - Finished"; + return ret; } diff --git a/src-qt5/src-glwidgets/gltest/test b/src-qt5/src-glwidgets/gltest/test Binary files differindex 85760654..3ba6f8db 100755 --- a/src-qt5/src-glwidgets/gltest/test +++ b/src-qt5/src-glwidgets/gltest/test diff --git a/src-qt5/src-glwidgets/glw-base.cpp b/src-qt5/src-glwidgets/glw-base.cpp index ef54606b..4065f70f 100644 --- a/src-qt5/src-glwidgets/glw-base.cpp +++ b/src-qt5/src-glwidgets/glw-base.cpp @@ -67,7 +67,24 @@ void GLW_Base::resizeEvent(QResizeEvent *ev){ }*/ void GLW_Base::paintGL(){ + //Setup the OpenGL stuff + QOpenGLFunctions *f = this->context()->functions(); + f->glViewport(0, 0, width(), height()); + f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + GLfloat vertices[] = { + 0.0f, 0.707f, + -0.5f, -0.5f, + 0.5f, -0.5f + }; + + f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(0); + f->glDrawArrays(GL_TRIANGLES, 0, 3); + f->glDisableVertexAttribArray(0); + glDrawPixels(bg_img.width(), bg_img.height(), GL_RGBA, GL_UNSIGNED_BYTE, bg_img.bits()); + QRect rect = QRect(QPoint(0,0), this->size()); //Prepare the image to be painted QImage img(this->size(), QImage::Format_RGBA8888); @@ -75,10 +92,6 @@ void GLW_Base::paintGL(){ painter.begin(&img); painter.fillRect(rect, bg_color); painter.end(); - QOpenGLFunctions *f = this->context()->functions(); - //f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //do native OpenGL commands here - glDrawPixels(bg_img.width(), bg_img.height(), GL_RGBA, GL_UNSIGNED_BYTE, bg_img.bits()); //Now do any QPainter drawing /*QOpenGLPaintDevice device(rect.size()); |