1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
package com.android.launcher3
import android.content.ComponentName
import android.view.View
import com.android.launcher3.DropTarget.DragObject
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
import com.android.launcher3.dragndrop.DragLayer
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.util.IntSet
import com.android.launcher3.util.PendingRequestArgs
import com.android.launcher3.views.Snackbar
/**
* Handler class for drop target actions that require modifying or interacting with launcher.
*
* This class is created by Launcher and provided the instance of launcher when created, which
* allows us to decouple drop target controllers from Launcher to enable easier testing.
*/
class DropTargetHandler(launcher: Launcher) {
val mLauncher: Launcher = launcher
fun onDropAnimationComplete() {
mLauncher.stateManager.goToState(LauncherState.NORMAL)
}
fun onSecondaryTargetCompleteDrop(target: ComponentName?, d: DragObject) {
when (val dragSource = d.dragSource) {
is DeferredOnComplete -> {
val deferred: DeferredOnComplete = dragSource
if (d.dragSource is SecondaryDropTarget.DeferredOnComplete) {
target?.let {
deferred.mPackageName = it.packageName
mLauncher.addOnResumeCallback { deferred.onLauncherResume() }
}
?: deferred.sendFailure()
}
}
}
}
fun reconfigureWidget(widgetId: Int, info: ItemInfo) {
mLauncher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(widgetId, null, info))
mLauncher.appWidgetHolder.startConfigActivity(
mLauncher,
widgetId,
Launcher.REQUEST_RECONFIGURE_APPWIDGET
)
}
fun dismissPrediction(
announcement: CharSequence,
onActionClicked: Runnable,
onDismiss: Runnable?
) {
mLauncher.dragLayer.announceForAccessibility(announcement)
Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, onDismiss, onActionClicked)
}
fun getViewUnderDrag(info: ItemInfo): View? {
return if (
info is LauncherAppWidgetInfo &&
info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
mLauncher.workspace.dragInfo != null
) {
mLauncher.workspace.dragInfo.cell
} else null
}
fun prepareToUndoDelete() {
mLauncher.modelWriter.prepareToUndoDelete()
}
fun onDeleteComplete(item: ItemInfo) {
var pageItem: ItemInfo = item
if (item.container <= 0) {
val v = mLauncher.workspace.getHomescreenIconByItemId(item.container)
v?.let { pageItem = v.tag as ItemInfo }
}
val pageIds =
if (pageItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP)
IntSet.wrap(pageItem.screenId)
else mLauncher.workspace.currentPageScreenIds
val onUndoClicked = Runnable {
mLauncher.setPagesToBindSynchronously(pageIds)
mLauncher.modelWriter.abortDelete()
mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
}
Snackbar.show(
mLauncher,
R.string.item_removed,
R.string.undo,
mLauncher.modelWriter::commitDelete,
onUndoClicked
)
}
fun onAccessibilityDelete(view: View?, item: ItemInfo, announcement: CharSequence) {
// Remove the item from launcher and the db, we can ignore the containerInfo in this call
// because we already remove the drag view from the folder (if the drag originated from
// a folder) in Folder.beginDrag()
mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop")
mLauncher.workspace.stripEmptyScreens()
mLauncher.dragLayer.announceForAccessibility(announcement)
}
fun getDragLayer(): DragLayer {
return mLauncher.dragLayer
}
fun onClick(buttonDropTarget: ButtonDropTarget) {
mLauncher.accessibilityDelegate.handleAccessibleDrop(buttonDropTarget, null, null)
}
}
|