Skip to content

Commit

Permalink
refactor: prepare for support of fullscreen DnD
Browse files Browse the repository at this point in the history
着手准备全屏启动器拖拽功能的支持。当前状态仍存在一些问题,故此提交未启用拖放。

Log:
  • Loading branch information
BLumia committed Nov 20, 2023
1 parent cecd6b2 commit ecf8dd6
Show file tree
Hide file tree
Showing 15 changed files with 371 additions and 67 deletions.
4 changes: 4 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
#include <DStandardPaths>
#include <DPathBuf>
#include <launcherappiconprovider.h>
#include <launcherfoldericonprovider.h>
#include <blurhashimageprovider.h>
#include <ksortfilterproxymodel.h>
#include <multipagesortfilterproxymodel.h>

DCORE_USE_NAMESPACE
DGUI_USE_NAMESPACE
Expand Down Expand Up @@ -78,6 +80,7 @@ int main(int argc, char* argv[])
}

qmlRegisterType<KSortFilterProxyModel>("org.deepin.vendored", 1, 0, "KSortFilterProxyModel");
qmlRegisterType<MultipageSortFilterProxyModel>("org.deepin.launchpad", 1, 0, "MultipageSortFilterProxyModel");
qmlRegisterUncreatableType<AppItem>("org.deepin.launchpad", 1, 0, "AppItem", "AppItem should only be created from C++ side");
qmlRegisterSingletonInstance("org.deepin.launchpad", 1, 0, "AppsModel", &AppsModel::instance());
qmlRegisterSingletonInstance("org.deepin.launchpad", 1, 0, "FavoritedProxyModel", &FavoritedProxyModel::instance());
Expand All @@ -95,6 +98,7 @@ int main(int argc, char* argv[])
QQuickStyle::setStyle("Chameleon");

engine.addImageProvider(QLatin1String("app-icon"), new LauncherAppIconProvider);
engine.addImageProvider(QLatin1String("folder-icon"), new LauncherFolderIconProvider);
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);

QQmlContext * ctx = engine.rootContext();
Expand Down
25 changes: 1 addition & 24 deletions qml/AppListView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,7 @@ Item {
if (CategorizedSortProxyModel.categoryType === CategorizedSortProxyModel.Alphabetary) {
return section.toUpperCase();
} else {
switch (Number(section)) {
case AppItem.Internet:
return qsTr("Internet");
case AppItem.Chat:
return qsTr("Chat");
case AppItem.Music:
return qsTr("Music");
case AppItem.Video:
return qsTr("Video");
case AppItem.Graphics:
return qsTr("Graphics");
case AppItem.Game:
return qsTr("Game");
case AppItem.Office:
return qsTr("Office");
case AppItem.Reading:
return qsTr("Reading");
case AppItem.Development:
return qsTr("Development");
case AppItem.System:
return qsTr("System");
default:
return qsTr("Others");
}
return getCategoryName(section)
}
}

Expand Down
69 changes: 56 additions & 13 deletions qml/FullscreenFrame.qml
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,13 @@ Control {
sourceComponent: Rectangle {
color: "transparent"

KSortFilterProxyModel {
property var grids: gridViewContainer

MultipageSortFilterProxyModel {
id: proxyModel
sourceModel: MultipageProxyModel
filterRowCallback: (source_row, source_parent) => {
var index = sourceModel.index(source_row, 0, source_parent);
return sourceModel.data(index, MultipageProxyModel.PageRole) === modelData &&
sourceModel.data(index, MultipageProxyModel.FolderIdNumberRole) === 0;
}
pageId: modelData
folderId: 0
}

GridViewContainer {
Expand All @@ -149,6 +148,12 @@ Control {
focus: true
activeGridViewFocusOnTab: gridViewLoader.SwipeView.isCurrentItem
delegate: IconItemDelegate {
dndEnabled: false
Drag.mimeData: {
"application/x-dde-launcher-dnd-fullscreen": ("0," + modelData + "," + index), // "folder,page,index"
"application/x-dde-launcher-dnd-desktopId": model.desktopId
}
visible: model.desktopId !== dropArea.currentDraggedDesktopId
iconSource: "image://app-icon/" + iconName
width: gridViewContainer.cellSize
height: gridViewContainer.cellSize
Expand All @@ -162,7 +167,7 @@ Control {
let idNum = Number(idStr.replace("internal/folders/", ""))
folderLoader.currentFolderId = idNum
folderGridViewPopup.open()
folderLoader.folderName = model.display
folderLoader.folderName = model.display.startsWith("internal/category/") ? getCategoryName(model.display.substring(18)) : model.display
console.log("open folder id:" + idNum)
}
onMenuTriggered: {
Expand Down Expand Up @@ -236,6 +241,47 @@ Control {
}
}

DropArea {
id: dropArea
anchors.fill: parent

property string currentDraggedDesktopId: ""

onPositionChanged: {
currentDraggedDesktopId = drag.getDataAsString("application/x-dde-launcher-dnd-desktopId")
dndDebug.text = drag.x + "," + drag.y + "." + drag.getDataAsString("application/x-dde-launcher-dnd-desktopId")
}

onDropped: {
let curGridView = pages.currentItem.item.grids
let curPoint = curGridView.mapFromItem(dropArea, drag.x, drag.y)
let curItem = curGridView.itemAt(curPoint.x, curPoint.y)
if (curItem) {
// drop on the left, center or right?
let itemX = curGridView.mapFromItem(curItem.parent, curItem.x, curItem.y).x
let itemWidth = curItem.width
let sideOpPadding = itemWidth / 4
let op = 0
if (curPoint.x < (itemX + sideOpPadding)) {
op = -1
} else if (curPoint.x > (itemX + curItem.width - sideOpPadding)) {
op = 1
}

let targetItemInfo = curItem.Drag.mimeData["application/x-dde-launcher-dnd-desktopId"]
dndDebug.text = "drag " + currentDraggedDesktopId + " onto " + targetItemInfo + " with " + op
MultipageProxyModel.commitDndOperation(currentDraggedDesktopId, targetItemInfo, op)
}
currentDraggedDesktopId = ""
}

Label {
id: dndDebug
visible: DebugHelper.qtDebugEnabled
text: "DnD DEBUG"
}
}

Popup {
id: folderGridViewPopup

Expand Down Expand Up @@ -301,14 +347,11 @@ Control {
anchors.fill: parent
color: "transparent"

KSortFilterProxyModel {
MultipageSortFilterProxyModel {
id: folderProxyModel
sourceModel: MultipageProxyModel
filterRowCallback: (source_row, source_parent) => {
var index = sourceModel.index(source_row, 0, source_parent);
return sourceModel.data(index, MultipageProxyModel.PageRole) === modelData &&
sourceModel.data(index, MultipageProxyModel.FolderIdNumberRole) === folderLoader.currentFolderId;
}
pageId: modelData
folderId: folderLoader.currentFolderId
}

GridViewContainer {
Expand Down
6 changes: 6 additions & 0 deletions qml/GridViewContainer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ FocusScope {
visible: gridView.activeFocus
}
}

// working (on drag into folder):
displaced: Transition { NumberAnimation { properties: "x,y"; duration: 250 } }
// not wroking
move: Transition { NumberAnimation { properties: "x,y"; duration: 250 } }
moveDisplaced: Transition { NumberAnimation { properties: "x,y"; duration: 250 } }
}
}

Expand Down
64 changes: 38 additions & 26 deletions qml/IconItemDelegate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,29 @@ Control {
property int preferredIconSize: 48

property string iconSource
property bool dndEnabled: false

Accessible.name: iconItemLabel.text

signal folderClicked()
signal itemClicked()
signal menuTriggered()

Drag.dragType: Drag.Automatic
Drag.active: dragHandler.active

states: State {
name: "dragged";
when: dragHandler.active
// FIXME: When dragging finished, the position of the item is changed for unknown reason,
// so we use the state to reset the x and y here.
PropertyChanges {
target: root
x: x
y: y
}
}

contentItem: ToolButton {
focusPolicy: Qt.NoFocus
contentItem: Column {
Expand All @@ -48,44 +64,25 @@ Control {
radius: width / 2
}

Rectangle {
Item {
width: root.width / 2
height: root.height / 2
anchors.horizontalCenter: parent.horizontalCenter
radius: 8
color: root.icons ? Qt.rgba(0, 0, 0, 0.5) : "transparent"

Loader {
id: iconLoader
anchors.fill: parent
sourceComponent: root.icons !== undefined ? folderComponent : imageComponent
}

Component {
id: folderComponent

Grid {
id: folderGrid
Image {
id: iconImage
anchors.fill: parent
rows: 2
columns: 2
spacing: 5
padding: 5

Repeater {
model: icons
delegate: Rectangle {
visible: true
color: "transparent"
width: (folderGrid.width - (folderGrid.columns - 1) * folderGrid.spacing - folderGrid.padding * 2) / folderGrid.columns
height: (folderGrid.height - (folderGrid.rows - 1) * folderGrid.spacing - folderGrid.padding * 2) / folderGrid.rows

Image {
anchors.fill: parent
source: "image://app-icon/" + modelData
sourceSize: Qt.size(parent.width, parent.height)
}
}
}
source: "image://folder-icon/" + icons.join(':')
sourceSize: Qt.size(parent.width, parent.height)
}
}

Expand All @@ -104,7 +101,7 @@ Control {

Label {
id: iconItemLabel
text: display
text: display.startsWith("internal/category/") ? getCategoryName(display.substring(18)) : display
textFormat: Text.PlainText
width: parent.width
horizontalAlignment: Text.AlignHCenter
Expand Down Expand Up @@ -141,6 +138,21 @@ Control {
id: stylus
}

DragHandler {
id: dragHandler
enabled: root.dndEnabled

onActiveChanged: {
if (active) {
// TODO: 1. this way we couldn't give it an image size hint,
// 2. also not able to set offset to drag image, so the cursor is always
// at the top-left of the image
// 3. we should also handle folder icon
parent.Drag.imageSource = icons ? ("image://folder-icon/" + icons.join(':')) : parent.iconSource
}
}
}

Keys.onSpacePressed: {
root.itemClicked()
}
Expand Down
27 changes: 27 additions & 0 deletions qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,33 @@ ApplicationWindow {
}
}

function getCategoryName(section) {
switch (Number(section)) {
case AppItem.Internet:
return qsTr("Internet");
case AppItem.Chat:
return qsTr("Chat");
case AppItem.Music:
return qsTr("Music");
case AppItem.Video:
return qsTr("Video");
case AppItem.Graphics:
return qsTr("Graphics");
case AppItem.Game:
return qsTr("Game");
case AppItem.Office:
return qsTr("Office");
case AppItem.Reading:
return qsTr("Reading");
case AppItem.Development:
return qsTr("Development");
case AppItem.System:
return qsTr("System");
default:
return qsTr("Others");
}
}

function descaledRect(rect) {
let ratio = Screen.devicePixelRatio
return Qt.rect(rect.left / ratio, rect.top / ratio, rect.width / ratio, rect.height / ratio)
Expand Down
2 changes: 2 additions & 0 deletions src/models/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ FILES
categorizedsortproxymodel.h
favoritedproxymodel.h
multipageproxymodel.h
multipagesortfilterproxymodel.h
)

target_sources(launcher-models
Expand All @@ -23,6 +24,7 @@ PRIVATE
favoritedproxymodel.cpp
itemspage.cpp itemspage.h
multipageproxymodel.cpp
multipagesortfilterproxymodel.cpp
)

target_link_libraries(launcher-models PRIVATE
Expand Down
Loading

0 comments on commit ecf8dd6

Please sign in to comment.