Refactored ListView

pull/9/head
reionwong 5 years ago
parent 868545255b
commit d8c07c7edb

@ -1,8 +1,7 @@
<RCC>
<qresource prefix="/">
<file>qml/main.qml</file>
<file>qml/LauncherGridDelegate.qml</file>
<file>qml/PageView.qml</file>
<file>qml/LauncherGridView.qml</file>
<file>qml/GridItemDelegate.qml</file>
<file>qml/AllAppsView.qml</file>
</qresource>
</RCC>

@ -0,0 +1,155 @@
/*
* Copyright (C) 2021 CutefishOS.
*
* Author: Reoin Wong <reionwong@gmail.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import FishUI 1.0 as FishUI
import Cutefish.Launcher 1.0
ListView {
id: control
property bool searchMode: false
property var sourceModel: launcherModel
property var modelCount: sourceModel.count
property int iconSize: 128 + FishUI.Units.largeSpacing * 2
property int cellWidth: iconSize + calcExtraSpacing(iconSize, control.width)
property int cellHeight: iconSize + calcExtraSpacing(iconSize, control.height)
property int rows: control.width / control.cellWidth
property int columns: control.height / control.cellHeight
property int pageCount: control.rows * control.columns
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem
model: Math.ceil(control.modelCount / control.pageCount)
maximumFlickVelocity: 10000
highlightMoveDuration: 100
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightRangeMode: ListView.StrictlyEnforceRange
highlightFollowsCurrentItem: true
cacheBuffer: control.width * control.count
boundsBehavior: Flickable.DragOverBounds
currentIndex: 0
clip: true
NumberAnimation on contentX {
id: scrollAnim
duration: 300
easing.type: Easing.InOutQuad
onStopped: {
var index = control.indexAt(control.contentX + control.width / 2,
control.contentY + control.height / 2)
if (index === -1)
control.currentIndex = 0
else
control.currentIndex = index
}
}
MouseArea {
anchors.fill: parent
z: -1
onClicked: {
launcher.hideWindow()
}
onWheel: {
if (wheel.angleDelta.y > 0)
scrollPreviousPage()
else
scrollNextPage()
}
}
delegate: Flow {
id: _page
width: control.width
height: control.height
readonly property int pageIndex: index
move: Transition {
NumberAnimation {
properties: "x, y"
duration: 300
easing.type: Easing.InOutQuad
}
}
Repeater {
model: PageModel {
id: _pageModel
sourceModel: launcherModel
startIndex: control.pageCount * _page.pageIndex
limitCount: control.pageCount
}
delegate: GridItemDelegate {
searchMode: control.searchMode
pageIndex: _page.pageIndex
pageCount: control.pageCount
width: control.cellWidth
height: control.cellHeight
}
}
}
function calcExtraSpacing(cellSize, containerSize) {
var availableColumns = Math.floor(containerSize / cellSize)
var extraSpacing = 0
if (availableColumns > 0) {
var allColumnSize = availableColumns * cellSize
var extraSpace = Math.max(containerSize - allColumnSize, 0)
extraSpacing = extraSpace / availableColumns
}
return Math.floor(extraSpacing)
}
function scrollNextPage() {
if (scrollAnim.running)
return
if (currentIndex < count - 1) {
scrollAnim.to = control.currentItem.x + control.width
scrollAnim.restart()
}
}
function scrollPreviousPage() {
if (scrollAnim.running)
return
if (currentIndex > 0) {
scrollAnim.to = control.currentItem.x - control.width
scrollAnim.restart()
}
}
}

@ -27,9 +27,13 @@ import Cutefish.Launcher 1.0
Item {
id: control
property bool searchMode: false
property bool dragStarted: false
property var dragItemIndex: index
property int pageIndex: 0
property int pageCount: 0
Drag.active: iconMouseArea.drag.active
Drag.dragType: Drag.Automatic
Drag.supportedActions: Qt.MoveAction
@ -49,8 +53,16 @@ Item {
enabled: true
onContainsDragChanged: {
if (drag.source)
launcherModel.move(drag.source.dragItemIndex, control.dragItemIndex)
if (control.searchMode)
return
if (drag.source) {
launcherModel.move(drag.source.dragItemIndex,
control.dragItemIndex,
control.pageIndex,
control.pageCount)
_pageModel.move(drag.source.dragItemIndex, control.dragItemIndex)
}
}
}
@ -98,10 +110,10 @@ Item {
onTriggered: launcherModel.removeFromDock(model.appId)
}
MenuItem {
text: qsTr("Uninstall")
onTriggered: {}
}
// MenuItem {
// text: qsTr("Uninstall")
// onTriggered: {}
// }
function updateActions() {
sendToDock.visible = launcher.dockAvailable() && !launcher.isPinedDock(model.appId)

@ -1,65 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS.
*
* Author: revenmartin <revenmartin@gmail.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.12
import QtQuick.Window 2.12
import FishUI 1.0 as FishUI
import Cutefish.Launcher 1.0
PageView {
id: control
property int iconSize: 128 + FishUI.Units.largeSpacing * 2
property int cellWidth: {
var extraWidth = calcExtraSpacing(iconSize, control.width)
return iconSize + extraWidth
}
property int cellHeight: {
var extraHeight = calcExtraSpacing(iconSize, control.height)
return iconSize + extraHeight
}
columns: control.width / cellWidth
rows: control.height / cellHeight
model: launcherModel
delegate: Item {
width: cellWidth
height: cellHeight
LauncherGridDelegate {
id: delegate
anchors.fill: parent
}
}
function calcExtraSpacing(cellSize, containerSize) {
var availableColumns = Math.floor(containerSize / cellSize);
var extraSpacing = 0;
if (availableColumns > 0) {
var allColumnSize = availableColumns * cellSize;
var extraSpace = Math.max(containerSize - allColumnSize, 0);
extraSpacing = extraSpace / availableColumns;
}
return Math.floor(extraSpacing);
}
}

@ -1,113 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS.
*
* Author: revenmartin <revenmartin@gmail.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.12
import Cutefish.Launcher 1.0
Item {
id: pagedGrid
property var model
property int rows
property int columns
property Component delegate
readonly property var count: model.count
readonly property int pageCount: rows * columns
readonly property alias pages: pageView.count
property alias currentPage: pageView.currentIndex
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onWheel: {
if (wheel.angleDelta.y > 0)
pageView.decrementCurrentIndex();
else
pageView.incrementCurrentIndex();
}
}
ListView {
id: pageView
anchors.fill: parent
orientation: Qt.Horizontal
snapMode: ListView.SnapOneItem
highlightFollowsCurrentItem: true
highlightRangeMode: ListView.StrictlyEnforceRange
highlightMoveDuration: 500
currentIndex: 0
maximumFlickVelocity: 9000
preferredHighlightBegin: 0
preferredHighlightEnd: 0
cacheBuffer: pageView.width * pageView.count
boundsBehavior: Flickable.DragOverBounds
clip: true
// // Blank area
MouseArea {
anchors.fill: parent
z: -1
onClicked: launcher.hideWindow()
}
model: Math.ceil(pagedGrid.count / pageCount)
delegate: pageDelegate
}
Component {
id: pageDelegate
Flow {
id: _page
width: pagedGrid.width
height: pagedGrid.height
// columns: pagedGrid.columns
readonly property int pageIndex: index
// move: Transition {
// NumberAnimation {
// duration: 300
// easing.type: Easing.InOutQuad
// properties: "x,y"
// }
// }
Repeater {
model: PageModel {
id: _pageModel
sourceModel: pagedGrid.model
startIndex: pageCount * pageIndex
limitCount: pageCount
}
delegate: pagedGrid.delegate
}
}
}
}

@ -38,6 +38,21 @@ Item {
property real maxSpacing: horizontalSpacing > verticalSpacing ? horizontalSpacing : verticalSpacing
property bool showed: launcher.showed
onShowedChanged: {
if (showed)
searchFieldAni.start()
}
NumberAnimation {
id: searchFieldAni
from: 0.0
to: 1.0
target: textField
property: "opacity"
easing.type: Easing.InQuad
duration: 250
}
// onShowedChanged: {
// appViewOpacityAni.restart()
// blurAnimation.restart()
@ -103,7 +118,7 @@ Item {
fillMode: Image.PreserveAspectCrop
asynchronous: false
cache: false
smooth: false
smooth: true
}
FastBlur {
@ -214,6 +229,10 @@ Item {
}
}
Item {
height: 14
}
Item {
id: gridItem
Layout.fillHeight: true
@ -222,12 +241,13 @@ Item {
Keys.enabled: true
Keys.forwardTo: appView
LauncherGridView {
AllAppsView {
id: appView
anchors.fill: parent
anchors.leftMargin: gridItem.width * 0.1
anchors.rightMargin: gridItem.width * 0.1
Layout.alignment: Qt.AlignHCenter
searchMode: textField.text
focus: true
Keys.enabled: true
@ -262,9 +282,9 @@ Item {
PageIndicator {
id: pageIndicator
count: appView.pages
currentIndex: appView.currentPage
onCurrentIndexChanged: appView.currentPage = currentIndex
count: appView.count
currentIndex: appView.currentIndex
onCurrentIndexChanged: appView.currentIndex = currentIndex
interactive: true
spacing: FishUI.Units.largeSpacing
Layout.alignment: Qt.AlignHCenter

@ -25,10 +25,13 @@
class LauncherItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString fuke READ fuke CONSTANT)
public:
explicit LauncherItem(QObject *parent = nullptr);
Q_INVOKABLE QString fuke() { return "asd"; };
QString id;
QString name;
QString genericName;

@ -60,6 +60,14 @@ LauncherModel::LauncherModel(QObject *parent)
connect(this, &QAbstractItemModel::rowsRemoved, this, &LauncherModel::countChanged);
connect(this, &QAbstractItemModel::modelReset, this, &LauncherModel::countChanged);
connect(this, &QAbstractItemModel::layoutChanged, this, &LauncherModel::countChanged);
connect(this, &LauncherModel::refreshed, this, [=] {
beginResetModel();
std::sort(m_items.begin(), m_items.end(), [=] (LauncherItem *a, LauncherItem *b) {
return a->name < b->name;
});
endResetModel();
});
}
LauncherModel::~LauncherModel()
@ -240,19 +248,22 @@ int LauncherModel::indexFromAppId(const QString &appId) const
return -1;
}
void LauncherModel::move(int from, int to)
void LauncherModel::move(int from, int to, int page, int pageCount)
{
if (from == to)
return;
m_items.move(from, to);
int newFrom = from + (page * pageCount);
int newTo = to + (page * pageCount);
m_items.move(newFrom, newTo);
if (from < to)
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to + 1);
else
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
// if (from < to)
// beginMoveRows(QModelIndex(), from, from, QModelIndex(), to + 1);
// else
// beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
endMoveRows();
// endMoveRows();
}
bool LauncherModel::launch(const QString &path)

@ -73,7 +73,7 @@ public:
Q_INVOKABLE QString getIconName(const QString &appId);
Q_INVOKABLE int indexFromAppId(const QString &appId) const;
Q_INVOKABLE void move(int from, int to);
Q_INVOKABLE void move(int from, int to, int page, int pageCount);
public Q_SLOTS:
Q_INVOKABLE bool launch(const QString &path);

@ -41,7 +41,8 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QByteArray uri = "Cutefish.Launcher";
qmlRegisterUncreatableType<LauncherItem>(uri, 1, 0, "LauncherItem", "cannot init application");
// qmlRegisterUncreatableType<LauncherItem>(uri, 1, 0, "LauncherItem", "cannot init application");
qmlRegisterType<LauncherItem>(uri, 1, 0, "LauncherItem");
qmlRegisterType<LauncherModel>(uri, 1, 0, "LauncherModel");
qmlRegisterType<PageModel>(uri, 1, 0, "PageModel");
qmlRegisterType<IconItem>(uri, 1, 0, "IconItem");
@ -55,7 +56,7 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
app.setApplicationName(QStringLiteral("cutefish-launcher"));
QPixmapCache::setCacheLimit(1024 * 10);
// QPixmapCache::setCacheLimit(1024 * 10);
// QCommandLineParser parser;
// QCommandLineOption showOption(QStringLiteral("show"), "Show Launcher");

@ -37,6 +37,19 @@ int PageModel::startIndex() const { return m_startIndex; }
int PageModel::limitCount() const { return m_limitCount; }
void PageModel::move(int from, int to)
{
if (from == to)
return;
if (from < to)
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to + 1);
else
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
endMoveRows();
}
void PageModel::setStartIndex(int startIndex)
{
if (startIndex != m_startIndex) {

@ -39,6 +39,8 @@ public:
int startIndex() const;
int limitCount() const;
Q_INVOKABLE void move(int from, int to);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
public Q_SLOTS:

Loading…
Cancel
Save