feat: add filtering&sorting example

closes: status-im/status-desktop#6510
closes: status-im/status-desktop#6512
This commit is contained in:
Patryk Osmaczko 2022-07-19 12:29:18 +02:00 committed by osmaczko
parent df60ec047a
commit 9b89e08294
8 changed files with 240 additions and 9 deletions

View File

@ -8,6 +8,11 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# add_subdirectory(src)
# https://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html#importing-qml-modules
set(QML_IMPORT_PATH
${CMAKE_SOURCE_DIR}/src;${QML_IMPORT_PATH}
CACHE STRING "")
add_subdirectory(vendor/SortFilterProxyModel)
add_subdirectory(sandbox)
add_subdirectory(tests)

View File

@ -28,5 +28,6 @@ endif()
target_compile_definitions(${PROJECT_NAME}
PRIVATE SRC_DIR="${CMAKE_CURRENT_LIST_DIR}")
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick
Qt5::QuickControls2)
target_link_libraries(
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2
SortFilterProxyModel)

View File

@ -913,8 +913,19 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
notificationsCount: 0
}
ListElement {
sectionId: "demoApp"
sectionId: "examples"
sectionType: 101
name: "Examples"
active: false
image: ""
icon: "show"
color: ""
hasNotification: false
notificationsCount: 0
}
ListElement {
sectionId: "demoApp"
sectionType: 102
name: "Demo Application"
active: false
image: ""

View File

@ -0,0 +1,154 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
import SortFilterProxyModel 0.2
ColumnLayout {
id: root
RowLayout {
Layout.fillWidth: true
StatusIconTextButton {
id: sortBtn
property int sortOrder: -1
statusIcon: {
if (sortOrder == Qt.AscendingOrder) return "chevron-down"
if (sortOrder == Qt.DescendingOrder) return "chevron-up"
return "remove"
}
onClicked: {
var st = sortOrder + 1
sortOrder = st > 1 ? -1 : st
}
}
StatusInput {
id: searchInput
Layout.fillWidth: true
input.icon.name: "search"
input.placeholderText: "nickname.."
}
StatusIconTabButton {
id: contactBtn
icon.name: "tiny/tiny-contact"
identicon.icon.color: Theme.palette.primaryColor1
onClicked: highlighted = !highlighted
}
StatusIconTabButton {
id: verifiedBtn
icon.name: "tiny/tiny-checkmark"
identicon.icon.color: Theme.palette.primaryColor1
onClicked: highlighted = !highlighted
}
}
ListView {
Layout.fillWidth: true
implicitHeight: contentItem.childrenRect.height
spacing: 4
model: SortFilterProxyModel {
sourceModel: d.users
sorters: StringSorter {
enabled: sortBtn.sortOrder !== -1
roleName: "nick"
sortOrder: sortBtn.sortOrder
}
filters: [
ExpressionFilter {
expression: model.nick.startsWith(searchInput.text)
},
AllOf {
enabled: contactBtn.highlighted || verifiedBtn.highlighted
ValueFilter {
enabled: contactBtn.highlighted
roleName: "isContact"
value: true
}
ValueFilter {
enabled: verifiedBtn.highlighted
roleName: "isVerified"
value: true
}
}
]
}
delegate: StatusMemberListItem {
width: parent.width
userName: model.name
nickName: model.nick
isVerified: model.isVerified
isContact: model.isContact
}
}
QtObject {
id: d
readonly property ListModel users: ListModel {
ListElement {
name: "Richard"
nick: "Ricky"
isVerified: true
isContact: true
}
ListElement {
name: "Susan"
nick: "Sue"
isVerified: false
isContact: false
}
ListElement {
name: "Edward"
nick: "Ed"
isVerified: true
isContact: false
}
ListElement {
name: "Toomas"
nick: "Tommy"
isVerified: false
isContact: false
}
ListElement {
name: "Elizabeth"
nick: "Bess"
isVerified: true
isContact: true
}
ListElement {
name: "Thomas"
nick: "Tom"
isVerified: false
isContact: true
}
ListElement {
name: "Fernando"
nick: "Alonso"
isVerified: false
isContact: true
}
ListElement {
name: "Alexander"
nick: "Alex"
isVerified: true
isContact: false
}
}
}
}

View File

@ -4,6 +4,8 @@
#include "sandboxapp.h"
#include <qqmlsortfilterproxymodeltypes.h>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -12,6 +14,8 @@ int main(int argc, char *argv[])
SandboxApp app(argc, argv);
qqsfpm::registerTypes();
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", QByteArrayLiteral("1"));
app.setOrganizationName("Status");

View File

@ -4,6 +4,7 @@ import QtQuick.Controls 2.14
import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.14
import Qt.labs.settings 1.0
import QtQml.Models 2.14
import Sandbox 0.1
@ -14,6 +15,8 @@ import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Platform 0.1
import SortFilterProxyModel 0.2
import "demoapp/data" 1.0
StatusWindow {
@ -44,7 +47,8 @@ StatusWindow {
readonly property int nodeManagement: 4
readonly property int profileSettings: 5
readonly property int apiDocumentation: 100
readonly property int demoApp: 101
readonly property int examples: 101
readonly property int demoApp: 102
}
function setActiveItem(sectionId) {
@ -87,13 +91,16 @@ StatusWindow {
if(model.sectionType === appSectionType.apiDocumentation)
{
stackView.push(libraryDocumentationCmp)
rootWindow.setActiveItem(sectionId)
}
else if(model.sectionType === appSectionType.examples)
{
stackView.push(examplesCmp)
}
else if(model.sectionType === appSectionType.demoApp)
{
stackView.push(demoAppCmp)
rootWindow.setActiveItem(model.sectionId)
}
rootWindow.setActiveItem(model.sectionId)
}
}
}
@ -400,6 +407,53 @@ StatusWindow {
}
}
Component {
id: examplesCmp
StatusAppTwoPanelLayout {
id: examplesView
function example(name) {
examplesLoader.source = Qt.resolvedUrl("./examples/" + name + ".qml")
storeSettings.selectedExample = examplesLoader.source
}
readonly property string defaultExampleSource: example("FilteringSorting")
leftPanel: StatusScrollView {
id: examplesLeftPanel
anchors.fill: parent
anchors.topMargin: 48
ColumnLayout {
width: examplesLeftPanel.availableWidth
spacing: 0
StatusNavigationListItem {
Layout.fillWidth: true
title: "FilteringSorting"
selected: examplesLoader.source.toString().includes(title)
onClicked: examplesView.example(title)
}
}
}
rightPanel: StatusScrollView {
id: examplesRightPanel
anchors.fill: parent
anchors.margins: 64
anchors.topMargin: anchors.margins + 32
Loader {
id: examplesLoader
width: examplesRightPanel.availableWidth
source: storeSettings.selectedExample !== "" ? storeSettings.selectedExample : examplesView.defaultExampleSource
}
}
}
}
Component {
id: demoAppCmp
@ -494,6 +548,7 @@ StatusWindow {
Settings {
id: storeSettings
property string selected: ""
property string selectedExample: ""
property bool lightTheme: true
property bool fillPage: false
}

View File

@ -75,5 +75,6 @@
<file>DemoApp.qml</file>
<file>main.qml</file>
<file>ThemeSwitch.qml</file>
<file>examples/FilteringSorting.qml</file>
</qresource>
</RCC>

View File

@ -20,7 +20,7 @@ void SandboxApp::startEngine()
qmlRegisterType<SpellChecker>("Sandbox", 0, 1, "Spellchecker");
#ifdef QT_DEBUG
const QUrl url = QUrl::fromLocalFile(SRC_DIR + QString{"/main.qml"});
const QUrl url = QUrl::fromLocalFile(SRC_DIR + QStringLiteral("/main.qml"));
#else
const QUrl url(QStringLiteral("qrc:/main.qml"));
#endif
@ -29,7 +29,7 @@ void SandboxApp::startEngine()
#ifdef QT_DEBUG
m_engine.addImportPath(SRC_DIR + QString{"/../src"});
m_engine.addImportPath(SRC_DIR + QStringLiteral("/../src"));
#else
m_engine.addImportPath(QStringLiteral(":/"));
#endif