Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb47b92353 | |||
| 49db588226 | |||
| f2596aaa40 |
+4
-1
@@ -25,7 +25,9 @@ qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(${CMAKE_PROJECT_NAME}
|
||||
README.md
|
||||
LICENSE)
|
||||
LICENSE
|
||||
images/icons/icons8-video.svg
|
||||
)
|
||||
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
|
||||
PREFIX "/"
|
||||
FILES
|
||||
@@ -56,6 +58,7 @@ qt_add_resources(${CMAKE_PROJECT_NAME} "app_images"
|
||||
"images/icons/icons8-store.svg"
|
||||
"images/icons/icons8-user-account.svg"
|
||||
"images/icons/icons8-view-more.svg"
|
||||
"images/icons/icons8-video.svg"
|
||||
"images/kero/kero_build_1.png"
|
||||
"images/kero/kero_build_2.png"
|
||||
"images/kero/kero_build_3.png"
|
||||
|
||||
@@ -17,6 +17,7 @@ qt6_add_qml_module(KomplexHubContent
|
||||
"pages/SettingsPage.qml"
|
||||
"pages/UserProfilePage.qml"
|
||||
"pages/WallpaperSettingsPage.qml"
|
||||
QML_FILES pages/VideoSearchPage.qml
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -83,7 +83,27 @@ Rectangle {
|
||||
currentMenuButton = this
|
||||
|
||||
searchContainer.preferredHeight = 50
|
||||
// searchContainer.searchTerm = (pageLoader.page as ImageSearchPage).query
|
||||
}
|
||||
}
|
||||
|
||||
MenuButton {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
height: 64
|
||||
width: 100
|
||||
text: "Videos"
|
||||
|
||||
icon.height: 32
|
||||
icon.width: 32
|
||||
icon.url: "qrc:/images/icons/icons8-video.svg"
|
||||
|
||||
onTriggered: () => {
|
||||
pageLoader.page = "pages/VideoSearchPage.qml"
|
||||
|
||||
currentMenuButton.selected = false
|
||||
currentMenuButton = this
|
||||
|
||||
searchContainer.preferredHeight = 50
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +307,8 @@ Rectangle {
|
||||
{
|
||||
return (
|
||||
pageLoader.item instanceof ImageSearchPage ||
|
||||
pageLoader.item instanceof LiveSearchPage
|
||||
pageLoader.item instanceof LiveSearchPage ||
|
||||
pageLoader.item instanceof VideoSearchPage
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import KomplexHub
|
||||
import KomplexHub.Controls
|
||||
import KomplexHub.Kero
|
||||
import KomplexHubPlugin
|
||||
|
||||
Item
|
||||
{
|
||||
property string query
|
||||
readonly property bool searchable: true
|
||||
property int resultsPerRow: (resultsContainer.width - (Constants.largeMargin * 2)) / (resultWidth + Constants.mediumMargin)
|
||||
property int rows: ((resultsContainer.height - (Constants.largeMargin * 2)) / (resultHeight + Constants.mediumMargin))
|
||||
property int resultsPerPage: resultsPerRow * rows
|
||||
property int emptyWidth: (resultsContainer.width - (Constants.largeMargin * 2)) - (resultsPerRow * (resultWidth + Constants.mediumMargin))
|
||||
property int resultWidth: 256
|
||||
property int resultHeight: 245
|
||||
|
||||
id: videoSearchPageRoot
|
||||
|
||||
VideoSearchModel
|
||||
{
|
||||
id: searchModel
|
||||
query: videoSearchPageRoot.query
|
||||
resultsPerPage: videoSearchPageRoot.resultsPerPage
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors.fill: parent
|
||||
color: palette.base
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: resultsContainer
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: buttonBoxLayout.top
|
||||
|
||||
color: "transparent"
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: resultsView
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout
|
||||
{
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Constants.largeMargin
|
||||
|
||||
Item
|
||||
{
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: emptyWidth / 2
|
||||
Layout.maximumWidth: emptyWidth / 2
|
||||
}
|
||||
|
||||
GridLayout
|
||||
{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
columns: videoSearchPageRoot.resultsPerRow
|
||||
columnSpacing: Constants.mediumMargin
|
||||
rowSpacing: Constants.mediumMargin
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: searchModel
|
||||
|
||||
delegate: Item {
|
||||
width: resultWidth
|
||||
height: resultHeight
|
||||
|
||||
required property string uuid
|
||||
required property string author
|
||||
required property string authorId
|
||||
required property string authorUrl
|
||||
required property string thumbnail
|
||||
|
||||
SearchResultItem
|
||||
{
|
||||
anchors.fill: parent
|
||||
title: parent.author
|
||||
author: parent.author
|
||||
description: "Video provided by Pexels"
|
||||
thumbnail: parent.thumbnail
|
||||
uuid: parent.uuid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout
|
||||
{
|
||||
id: buttonBoxLayout
|
||||
height: 35
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: Constants.largeMargin
|
||||
|
||||
SquareButton
|
||||
{
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: 128
|
||||
|
||||
icon.source: "qrc:/images/icons/icons8-back.svg"
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
text: qsTr("Previous")
|
||||
enabled: searchModel.hasPreviousPage
|
||||
|
||||
onTriggered: () => searchModel.previousPage()
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
||||
SquareButton
|
||||
{
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: 128
|
||||
|
||||
icon.source: "qrc:/images/icons/icons8-next.svg"
|
||||
icon.height: 16
|
||||
icon.width: 16
|
||||
text: qsTr("Next")
|
||||
enabled: searchModel.hasNextPage
|
||||
|
||||
onTriggered: () => searchModel.nextPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeroErrorAvatar
|
||||
{
|
||||
id: errorOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
KeroNoResultsAvatar
|
||||
{
|
||||
id: noResultsOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
KeroLoadingAnimation
|
||||
{
|
||||
id: loadingOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
states: [
|
||||
State
|
||||
{
|
||||
name: "loading"
|
||||
when: searchModel.state == VideoSearchModel.Loading
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: loadingOverlay
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: resultsView
|
||||
opacity: 0
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "empty"
|
||||
when: searchModel.totalResults === 0
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: noResultsOverlay
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: resultsView
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: buttonBoxLayout
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "error"
|
||||
when: searchModel.state == VideoSearchModel.Error
|
||||
|
||||
PropertyChanges
|
||||
{
|
||||
target: errorOverlay
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges
|
||||
{
|
||||
target: resultsView
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -38,7 +38,7 @@ qt_add_qml_module(
|
||||
SOURCES paginators/featuredcubemapspaginator.h
|
||||
SOURCES paginators/searchshaderspaginator.h
|
||||
SOURCES paginators/searchcubemapspaginator.h
|
||||
SOURCES paginators/searchvideospaginator.h
|
||||
SOURCES paginators/videosearchpaginator.h
|
||||
SOURCES featuredpacksmodel.h
|
||||
SOURCES featuredpacksmodel.cpp
|
||||
SOURCES featuredimagesmodel.h
|
||||
@@ -52,6 +52,8 @@ qt_add_qml_module(
|
||||
SOURCES paginators/videopaginator.h
|
||||
SOURCES imagesearchmodel.cpp
|
||||
SOURCES imagesearchmodel.h
|
||||
SOURCES videosearchmodel.h
|
||||
SOURCES videosearchmodel.cpp
|
||||
|
||||
)
|
||||
|
||||
|
||||
+6
-6
@@ -16,8 +16,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef SEARCHVIDEOSPAGINATOR_H
|
||||
#define SEARCHVIDEOSPAGINATOR_H
|
||||
#ifndef VIDEOSEARCHPAGINATOR_H
|
||||
#define VIDEOSEARCHPAGINATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
@@ -29,12 +29,12 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "wallpaperpaginator.h"
|
||||
#include "videopaginator.h"
|
||||
|
||||
class KOMPLEX_EXPORT SearchVideosPaginator : public WallpaperPaginator
|
||||
class KOMPLEX_EXPORT VideoSearchPaginator : public VideoPaginator
|
||||
{
|
||||
public:
|
||||
explicit SearchVideosPaginator(QObject *parent = nullptr) : WallpaperPaginator(parent)
|
||||
explicit VideoSearchPaginator(QObject *parent = nullptr) : VideoPaginator(parent)
|
||||
{
|
||||
setUri(
|
||||
QString::fromUtf8(KOMPLEX_ENDPOINT_VIDEOS_SEARCH)
|
||||
@@ -42,4 +42,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SEARCHVIDEOSPAGINATOR_H
|
||||
#endif // VIDEOSEARCHPAGINATOR_H
|
||||
@@ -0,0 +1,288 @@
|
||||
#include "videosearchmodel.h"
|
||||
|
||||
VideoSearchModel::VideoSearchModel(QObject *parent) : QAbstractListModel{parent}
|
||||
{
|
||||
setState(Loading);
|
||||
|
||||
m_paginator = new VideoSearchPaginator(this);
|
||||
PaginationNotifier *notifier = static_cast<PaginationNotifier*>(m_paginator);
|
||||
|
||||
QObject::connect(
|
||||
notifier,
|
||||
&PaginationNotifier::resultsPerPageChanged,
|
||||
this,
|
||||
&VideoSearchModel::resultsPerPageChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
notifier,
|
||||
&PaginationNotifier::totalResultsChanged,
|
||||
this,
|
||||
&VideoSearchModel::totalResultsChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
notifier,
|
||||
&PaginationNotifier::totalPagesChanged,
|
||||
this,
|
||||
&VideoSearchModel::totalPagesChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
notifier,
|
||||
&PaginationNotifier::pageChanged,
|
||||
this,
|
||||
&VideoSearchModel::pageChanged
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
notifier,
|
||||
&PaginationNotifier::dataChanged,
|
||||
this,
|
||||
&VideoSearchModel::resetDataModel
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
m_paginator,
|
||||
&VideoSearchPaginator::queryChanged,
|
||||
this,
|
||||
&VideoSearchModel::queryChanged
|
||||
);
|
||||
}
|
||||
|
||||
auto VideoSearchModel::rowCount(const QModelIndex &) const -> int
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->count();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::data(const QModelIndex &index, int role) const -> QVariant
|
||||
{
|
||||
if(index.row() < 0 || m_paginator == nullptr)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
VideoCache dataPoint = m_data.at(index.row());
|
||||
|
||||
QVariant data;
|
||||
|
||||
switch(static_cast<DataRole>(role))
|
||||
{
|
||||
case UuidRole:
|
||||
data = dataPoint.id;
|
||||
break;
|
||||
case AuthorRole:
|
||||
data = dataPoint.author;
|
||||
break;
|
||||
case AuthorIdRole:
|
||||
data = dataPoint.authorId;
|
||||
break;
|
||||
case AuthorUrlRole:
|
||||
data = dataPoint.authorUrl;
|
||||
break;
|
||||
case DurationRole:
|
||||
data = dataPoint.duration;
|
||||
break;
|
||||
case ThumbnailRole:
|
||||
data = dataPoint.thumbnail;
|
||||
break;
|
||||
case UrlRole:
|
||||
data = dataPoint.url;
|
||||
break;
|
||||
case HeightRole:
|
||||
data = dataPoint.height;
|
||||
break;
|
||||
case WidthRole:
|
||||
data = dataPoint.width;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::index(int row, int column, const QModelIndex &parent) const -> QModelIndex
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if(row < 0 || row >= m_data.count())
|
||||
return {};
|
||||
|
||||
return createIndex(row, column, &m_data[row]);
|
||||
}
|
||||
|
||||
auto VideoSearchModel::columnCount(const QModelIndex &) const -> int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::parent(const QModelIndex &) const -> QModelIndex
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto VideoSearchModel::setData(const QModelIndex &, const QVariant &, int) -> bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::state() const -> VideoSearchModel::State
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::setState(State state) -> void
|
||||
{
|
||||
if (m_state == state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
emit stateChanged();
|
||||
}
|
||||
|
||||
auto VideoSearchModel::resetState() -> void
|
||||
{
|
||||
setState(Idle);
|
||||
}
|
||||
|
||||
auto VideoSearchModel::resetDataModel() -> void
|
||||
{
|
||||
setState(Loading);
|
||||
|
||||
//invalidate previous model data
|
||||
beginRemoveRows(QModelIndex(), 0, m_data.count());
|
||||
m_data.clear();
|
||||
endRemoveRows();
|
||||
|
||||
//signal new data
|
||||
beginInsertRows(QModelIndex(), 0, m_paginator->count() - 1);
|
||||
auto dataset = m_paginator->data();
|
||||
|
||||
for(const VideoCache& data : std::as_const(dataset))
|
||||
{
|
||||
m_data.append(data);
|
||||
}
|
||||
|
||||
endInsertRows();
|
||||
|
||||
setState(Idle);
|
||||
}
|
||||
|
||||
auto VideoSearchModel::hasNextPage() -> bool
|
||||
{
|
||||
return m_paginator->page() < m_paginator->totalPages();
|
||||
}
|
||||
|
||||
auto VideoSearchModel::hasPreviousPage() -> bool
|
||||
{
|
||||
return m_paginator->page() > 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::roleNames() const -> QHash<int, QByteArray>
|
||||
{
|
||||
return m_dataRoles;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::errorString() const -> QString
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::setErrorString(const QString &errorString) -> void
|
||||
{
|
||||
if (m_errorString == errorString)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_errorString = errorString;
|
||||
emit errorStringChanged();
|
||||
}
|
||||
|
||||
auto VideoSearchModel::resultsPerPage() const -> qsizetype
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->resultsPerPage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::setResultsPerPage(qsizetype resultsPerPage) -> void
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
m_paginator->setResultsPerPage(resultsPerPage);
|
||||
}
|
||||
}
|
||||
|
||||
auto VideoSearchModel::totalResults() const -> qsizetype
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->totalResults();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::nextPage() const -> void
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
m_paginator->next();
|
||||
}
|
||||
}
|
||||
|
||||
auto VideoSearchModel::previousPage() const -> void
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
m_paginator->previous();
|
||||
}
|
||||
}
|
||||
|
||||
auto VideoSearchModel::query() const -> QString
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->query();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
auto VideoSearchModel::setQuery(const QString &query) -> void
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
m_paginator->setQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
qsizetype VideoSearchModel::page() const
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->page();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto VideoSearchModel::totalPages() const -> qsizetype
|
||||
{
|
||||
if(m_paginator != nullptr)
|
||||
{
|
||||
return m_paginator->totalPages();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef VideoSearchModel_H
|
||||
#define VideoSearchModel_H
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
#include <QList>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QAbstractListModel>
|
||||
#include <QProcess>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include "paginators/videosearchpaginator.h"
|
||||
|
||||
/**
|
||||
* @brief The VideoSearchModel class
|
||||
*/
|
||||
class KOMPLEX_EXPORT VideoSearchModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Used to control the UI state
|
||||
*/
|
||||
enum State
|
||||
{
|
||||
Idle,
|
||||
Loading,
|
||||
Error
|
||||
};
|
||||
Q_ENUM(State)
|
||||
|
||||
/**
|
||||
* @brief Data roles used by the view to request data
|
||||
*/
|
||||
enum DataRole {
|
||||
UuidRole = Qt::UserRole + 1,
|
||||
AuthorRole,
|
||||
AuthorIdRole,
|
||||
AuthorUrlRole,
|
||||
DurationRole,
|
||||
ThumbnailRole,
|
||||
UrlRole,
|
||||
HeightRole,
|
||||
WidthRole
|
||||
};
|
||||
Q_ENUM(DataRole)
|
||||
|
||||
explicit VideoSearchModel(QObject *parent = nullptr);
|
||||
|
||||
auto rowCount(const QModelIndex &parent = QModelIndex()) const -> int override;
|
||||
|
||||
/**
|
||||
* @brief data
|
||||
* Used by the view to pull data from the model.
|
||||
* Required by QAbstractListModel
|
||||
* @param index
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
auto data(
|
||||
const QModelIndex &index,
|
||||
int role = Qt::DisplayRole
|
||||
) const -> QVariant override;
|
||||
|
||||
/**
|
||||
* @brief index
|
||||
* Used by the view to create an index for the data point.
|
||||
* Required by QAbstractListModel
|
||||
* @param row
|
||||
* @param column
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
auto index(
|
||||
int row,
|
||||
int column,
|
||||
const QModelIndex &parent = QModelIndex()
|
||||
) const -> QModelIndex override;
|
||||
|
||||
/**
|
||||
* @brief columnCount
|
||||
* Required by QAbstractListModel, but just returns 0
|
||||
* since we dont use cols
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
auto columnCount(
|
||||
const QModelIndex &parent = QModelIndex()
|
||||
) const -> int override;
|
||||
|
||||
/**
|
||||
* @brief parent
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
auto parent(const QModelIndex &index) const -> QModelIndex override;
|
||||
|
||||
/**
|
||||
* @brief setData
|
||||
* Required by QAbstractListModel but not used
|
||||
* @param index
|
||||
* @param value
|
||||
* @param role
|
||||
* @return true always
|
||||
*/
|
||||
auto setData(
|
||||
const QModelIndex &index,
|
||||
const QVariant &value,
|
||||
int role = Qt::EditRole
|
||||
) -> bool override;
|
||||
|
||||
/**
|
||||
* @brief state
|
||||
* Current Model State
|
||||
* @return
|
||||
*/
|
||||
auto state() const -> State;
|
||||
|
||||
/**
|
||||
* @brief roleNames
|
||||
* Used to tell the view what data roles are available
|
||||
* and their QML friendly names
|
||||
* @return
|
||||
*/
|
||||
auto roleNames() const -> QHash<int, QByteArray> override;
|
||||
|
||||
/**
|
||||
* @brief errorString
|
||||
* User-friendly error string to be reported to the user
|
||||
* @return
|
||||
*/
|
||||
auto errorString() const -> QString;
|
||||
|
||||
/**
|
||||
* @brief resultsPerPage
|
||||
* @return
|
||||
*/
|
||||
auto resultsPerPage() const -> qsizetype;
|
||||
|
||||
/**
|
||||
* @brief setResultsPerPage
|
||||
* @param resultsPerPage
|
||||
*/
|
||||
auto setResultsPerPage(qsizetype resultsPerPage) -> void;
|
||||
|
||||
/**
|
||||
* @brief totalResults
|
||||
* Total number of results available
|
||||
* @return
|
||||
*/
|
||||
auto totalResults() const -> qsizetype;
|
||||
|
||||
/**
|
||||
* @brief page
|
||||
* @return
|
||||
*/
|
||||
auto page() const -> qsizetype;
|
||||
|
||||
/**
|
||||
* @brief totalPages
|
||||
* Total pages based on the current resultsPerPage
|
||||
* @return
|
||||
*/
|
||||
auto totalPages() const -> qsizetype;
|
||||
|
||||
/**
|
||||
* @brief nextPage
|
||||
* Function for the QML frontend
|
||||
*/
|
||||
Q_INVOKABLE auto nextPage() const -> void;
|
||||
|
||||
/**
|
||||
* @brief previousPage
|
||||
* Function for the QML frontend
|
||||
*/
|
||||
Q_INVOKABLE auto previousPage() const -> void;
|
||||
|
||||
/**
|
||||
* @brief query
|
||||
* Current search query
|
||||
* @return
|
||||
*/
|
||||
auto query() const -> QString;
|
||||
|
||||
/**
|
||||
* @brief setQuery
|
||||
* Sets the current
|
||||
* @param query
|
||||
*/
|
||||
auto setQuery(const QString &query) -> void;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief setErrorString
|
||||
* @param errorString
|
||||
*/
|
||||
auto setErrorString(const QString &errorString) -> void;
|
||||
|
||||
/**
|
||||
* @brief setState
|
||||
* @param state
|
||||
*/
|
||||
auto setState(State state) -> void;
|
||||
|
||||
/**
|
||||
* @brief resetState
|
||||
*/
|
||||
auto resetState() -> void;
|
||||
|
||||
auto resetDataModel() -> void;
|
||||
|
||||
auto hasNextPage() -> bool;
|
||||
|
||||
auto hasPreviousPage() -> bool;
|
||||
|
||||
signals:
|
||||
auto stateChanged() -> void;
|
||||
auto errorStringChanged() -> void;
|
||||
auto resultsPerPageChanged() -> void;
|
||||
|
||||
auto pageChanged() -> void;
|
||||
auto totalResultsChanged() -> void;
|
||||
auto totalPagesChanged() -> void;
|
||||
auto queryChanged() -> void;
|
||||
|
||||
private:
|
||||
static inline const QHash<int, QByteArray> m_dataRoles =
|
||||
{
|
||||
{
|
||||
static_cast<int>(UuidRole),
|
||||
QByteArray("uuid")
|
||||
},
|
||||
{
|
||||
static_cast<int>(AuthorRole),
|
||||
QByteArray("author")
|
||||
},
|
||||
{
|
||||
static_cast<int>(AuthorIdRole),
|
||||
QByteArray("authorId")
|
||||
},
|
||||
{
|
||||
static_cast<int>(AuthorUrlRole),
|
||||
QByteArray("authorUrl")
|
||||
},
|
||||
{
|
||||
static_cast<int>(DurationRole),
|
||||
QByteArray("duration")
|
||||
},
|
||||
{
|
||||
static_cast<int>(ThumbnailRole),
|
||||
QByteArray("thumbnail")
|
||||
},
|
||||
{
|
||||
static_cast<int>(UrlRole),
|
||||
QByteArray("url")
|
||||
},
|
||||
{
|
||||
static_cast<int>(HeightRole),
|
||||
QByteArray("height")
|
||||
},
|
||||
{
|
||||
static_cast<int>(WidthRole),
|
||||
QByteArray("width")
|
||||
}
|
||||
};
|
||||
State m_state = Idle;
|
||||
|
||||
QString m_errorString = QString();
|
||||
|
||||
VideoSearchPaginator *m_paginator = nullptr;
|
||||
|
||||
mutable QList<VideoCache> m_data;
|
||||
|
||||
Q_PROPERTY(State state READ state WRITE setState RESET resetState NOTIFY stateChanged FINAL)
|
||||
Q_PROPERTY(QString errorString READ errorString WRITE setErrorString NOTIFY errorStringChanged FINAL)
|
||||
Q_PROPERTY(qsizetype resultsPerPage READ resultsPerPage WRITE setResultsPerPage NOTIFY resultsPerPageChanged FINAL)
|
||||
Q_PROPERTY(qsizetype totalResults READ totalResults NOTIFY totalResultsChanged FINAL)
|
||||
Q_PROPERTY(qsizetype totalPages READ totalPages NOTIFY totalPagesChanged FINAL)
|
||||
Q_PROPERTY(qsizetype page READ page NOTIFY pageChanged FINAL)
|
||||
Q_PROPERTY(bool hasNextPage READ hasNextPage NOTIFY pageChanged FINAL)
|
||||
Q_PROPERTY(bool hasPreviousPage READ hasPreviousPage NOTIFY pageChanged FINAL)
|
||||
Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged FINAL)
|
||||
};
|
||||
Q_DECLARE_METATYPE(VideoSearchModel)
|
||||
|
||||
#endif // VideoSearchModel_H
|
||||
@@ -0,0 +1 @@
|
||||
Icons are licesened through Icons8.com via donation. They can not be distributed for use outside Komplex and its associated applications. All rights reserved to Icons8.
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
||||
<path d="M0 0 C31.68 0 63.36 0 96 0 C96 27.72 96 55.44 96 84 C64.32 84 32.64 84 0 84 C0 56.28 0 28.56 0 0 Z M4 4 C4 5.98 4 7.96 4 10 C5.98 10 7.96 10 10 10 C10 8.02 10 6.04 10 4 C8.02 4 6.04 4 4 4 Z M14 4 C14 5.98 14 7.96 14 10 C16.64 10 19.28 10 22 10 C22 8.02 22 6.04 22 4 C19.36 4 16.72 4 14 4 Z M26 4 C26 5.98 26 7.96 26 10 C28.64 10 31.28 10 34 10 C34 8.02 34 6.04 34 4 C31.36 4 28.72 4 26 4 Z M38 4 C38 5.98 38 7.96 38 10 C40.64 10 43.28 10 46 10 C46 8.02 46 6.04 46 4 C43.36 4 40.72 4 38 4 Z M50 4 C50 5.98 50 7.96 50 10 C52.64 10 55.28 10 58 10 C58 8.02 58 6.04 58 4 C55.36 4 52.72 4 50 4 Z M62 4 C62 5.98 62 7.96 62 10 C64.64 10 67.28 10 70 10 C70 8.02 70 6.04 70 4 C67.36 4 64.72 4 62 4 Z M74 4 C74 5.98 74 7.96 74 10 C76.64 10 79.28 10 82 10 C82 8.02 82 6.04 82 4 C79.36 4 76.72 4 74 4 Z M86 4 C86 5.98 86 7.96 86 10 C87.98 10 89.96 10 92 10 C92 8.02 92 6.04 92 4 C90.02 4 88.04 4 86 4 Z M4 14 C4 32.48 4 50.96 4 70 C33.04 70 62.08 70 92 70 C92 51.52 92 33.04 92 14 C62.96 14 33.92 14 4 14 Z M4 74 C4 75.98 4 77.96 4 80 C5.98 80 7.96 80 10 80 C10 78.02 10 76.04 10 74 C8.02 74 6.04 74 4 74 Z M14 74 C14 75.98 14 77.96 14 80 C16.64 80 19.28 80 22 80 C22 78.02 22 76.04 22 74 C19.36 74 16.72 74 14 74 Z M26 74 C26 75.98 26 77.96 26 80 C28.64 80 31.28 80 34 80 C34 78.02 34 76.04 34 74 C31.36 74 28.72 74 26 74 Z M38 74 C38 75.98 38 77.96 38 80 C40.64 80 43.28 80 46 80 C46 78.02 46 76.04 46 74 C43.36 74 40.72 74 38 74 Z M50 74 C50 75.98 50 77.96 50 80 C52.64 80 55.28 80 58 80 C58 78.02 58 76.04 58 74 C55.36 74 52.72 74 50 74 Z M62 74 C62 75.98 62 77.96 62 80 C64.64 80 67.28 80 70 80 C70 78.02 70 76.04 70 74 C67.36 74 64.72 74 62 74 Z M74 74 C74 75.98 74 77.96 74 80 C76.64 80 79.28 80 82 80 C82 78.02 82 76.04 82 74 C79.36 74 76.72 74 74 74 Z M86 74 C86 75.98 86 77.96 86 80 C87.98 80 89.96 80 92 80 C92 78.02 92 76.04 92 74 C90.02 74 88.04 74 86 74 Z " fill="#DADADA" transform="translate(2,8)"/>
|
||||
<path d="M0 0 C4.9473515 0 5.80671024 0.11866791 9.64453125 2.625 C10.48564453 3.16640625 11.32675781 3.7078125 12.19335938 4.265625 C13.05767578 4.83796875 13.92199219 5.4103125 14.8125 6 C15.69615234 6.57234375 16.57980469 7.1446875 17.49023438 7.734375 C19.66693565 9.14628934 21.83627774 10.56830696 24 12 C23.49355928 16.53837775 23.49355928 16.53837775 21.31347656 18.57739258 C20.59643555 19.01204834 19.87939453 19.4467041 19.140625 19.89453125 C18.35429688 20.37470703 17.56796875 20.85488281 16.7578125 21.34960938 C15.51644531 22.07374023 15.51644531 22.07374023 14.25 22.8125 C13.03183594 23.56563477 13.03183594 23.56563477 11.7890625 24.33398438 C7.27598993 27.03521266 5.5061171 28 0 28 C0 18.76 0 9.52 0 0 Z M4 7 C4 11.62 4 16.24 4 21 C7.23396985 19.70641206 9.88479853 18.59717733 12.8125 16.875 C14.3903125 15.946875 14.3903125 15.946875 16 15 C16 14.34 16 13.68 16 13 C13.82248821 11.40222476 13.82248821 11.40222476 11.125 9.875 C10.22007813 9.33617187 9.31515625 8.79734375 8.3828125 8.2421875 C6.15227978 6.8459107 6.15227978 6.8459107 4 7 Z " fill="#DADADA" transform="translate(40,36)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
Reference in New Issue
Block a user