1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { 17 LauncherDragItemInfo, 18 Log, 19 CommonConstants, 20 PresetStyleConstants, 21 localEventManager, 22 EventConstants, 23 FolderData, 24 BadgeManager, 25 CheckEmptyUtils 26} from '@ohos/common'; 27import AppItem from './AppItem'; 28import FormItem from './FormItem'; 29import FolderItem from './FolderItem'; 30import { PageDesktopGridStyleConfig } from '../PageDesktopGridStyleConfig'; 31import { PageDesktopDragHandler } from '../PageDesktopDragHandler'; 32import { PageDesktopViewModel } from '../../viewmodel/PageDesktopViewModel'; 33 34const TAG = 'SwiperPage'; 35 36interface AppListInfo { 37 appGridInfo: LauncherDragItemInfo[][] 38} 39 40interface GridLayout { 41 id: number; 42 layout: string; 43 name: string; 44 value: number; 45 row: number; 46 column: number; 47 checked: boolean; 48} 49 50@Component 51export default struct SwiperPage { 52 @StorageLink('workSpaceWidth') @Watch('updateDeskTopScreen') workSpaceWidth: number = 0; 53 @StorageLink('formRefresh') formRefresh: string = ''; 54 @State columnsTemplate: string = ''; 55 @State rowsTemplate: string = '' 56 @Prop @Watch('changeColumnAndRow') gridConfig: string; 57 @State mMargin: number = 0; 58 @State mColumnsGap: number = 0; 59 @State mRowsGap: number = 0; 60 @State mPaddingTop: number = 0; 61 @State mNameLines: number = PresetStyleConstants.DEFAULT_APP_NAME_LINES; 62 @State mMarginTop: number = 0; 63 @Link @Watch('updateAppListInfo') appListInfo: AppListInfo; 64 @Prop swiperPage: number; 65 @State mAppListInfo: LauncherDragItemInfo[] = this.appListInfo.appGridInfo[this.swiperPage]; 66 private mPageDesktopViewModel?: PageDesktopViewModel; 67 private mPageDesktopStyleConfig = PageDesktopViewModel.getInstance().getPageDesktopStyleConfig(); 68 private mGridWidth: number = 0; 69 private mGridHeight: number = 0; 70 private mIconSize: number = 0; 71 private mGridSpaceWidth: number = 0; 72 private mGridSpaceHeight: number = 0; 73 private APP_INFO_REFRESH_DELAY: number = 1000; 74 75 private updateAppListInfo(): void { 76 this.mAppListInfo = this.appListInfo.appGridInfo[this.swiperPage]; 77 this.updateOpenFolderData(); 78 } 79 80 /** 81 * 监听桌面元素变化时,更新打开的大文件的数据。 82 * eg:应用角标更新时,大文件内的应用角标同步更新。 83 */ 84 updateOpenFolderData() { 85 const openFolderData = AppStorage.get('openFolderData') as FolderData; 86 if (CheckEmptyUtils.isEmptyArr(this.mAppListInfo)) { 87 Log.showError(TAG, 'mAppListInfo is empty'); 88 return; 89 } 90 if (openFolderData?.folderId && this.mAppListInfo?.length) { 91 let temp = this.mAppListInfo.find((item: LauncherDragItemInfo) => item?.folderId === openFolderData.folderId); 92 AppStorage.setOrCreate('openFolderData', temp as FolderData); 93 } 94 } 95 96 aboutToAppear(): void { 97 Log.showInfo(TAG, 'aboutToAppear'); 98 this.mPageDesktopViewModel = PageDesktopViewModel.getInstance(); 99 this.updateDeskTopScreen(); 100 } 101 102 updateDeskTopScreen(): void { 103 Log.showInfo(TAG, 'updateDeskTopScreen'); 104 this.mPageDesktopStyleConfig = 105 this.mPageDesktopViewModel?.getPageDesktopStyleConfig() as PageDesktopGridStyleConfig; 106 this.mMargin = this.mPageDesktopStyleConfig.mMargin; 107 this.mColumnsGap = this.mPageDesktopStyleConfig.mColumnsGap; 108 this.mRowsGap = this.mPageDesktopStyleConfig.mRowsGap; 109 this.mPaddingTop = this.mPageDesktopStyleConfig.mPaddingTop; 110 this.mNameLines = this.mPageDesktopStyleConfig.mNameLines; 111 this.mMarginTop = this.mPageDesktopStyleConfig.mDesktopMarginTop; 112 this.mGridWidth = this.mPageDesktopStyleConfig.mGridWidth; 113 this.mGridHeight = this.mPageDesktopStyleConfig.mGridHeight; 114 this.mIconSize = this.mPageDesktopStyleConfig.mIconSize; 115 this.mGridSpaceWidth = Number(this.mPageDesktopViewModel?.getWorkSpaceWidth()) - this.mMargin; 116 this.mGridSpaceHeight = Number(this.mPageDesktopViewModel?.getWorkSpaceHeight()); 117 this.changeConfig(); 118 localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null); 119 } 120 121 private changeColumnAndRow(): void { 122 this.changeConfig(); 123 } 124 125 private changeConfig(): void { 126 let mGridConfig = this.mPageDesktopViewModel?.getGridConfig() as GridLayout; 127 let column = mGridConfig.column as number; 128 let row = mGridConfig.row as number; 129 this.columnsTemplate = ''; 130 this.rowsTemplate = ''; 131 for (let i = 0; i < column; i++) { 132 this.columnsTemplate += '1fr ' 133 } 134 for (let i = 0; i < row; i++) { 135 this.rowsTemplate += '1fr ' 136 } 137 } 138 139 itemMove(moveX: number, moveY: number): void { 140 const isSwappingPage: boolean = AppStorage.get('isSwappingPage') as boolean; 141 if (isSwappingPage) { 142 return; 143 } 144 let curPageIndex: number = AppStorage.get('pageIndex') as number; 145 if ((moveX - this.mIconSize / 2) < this.mMargin && curPageIndex > 0 && moveY < this.mGridSpaceHeight) { 146 this.mPageDesktopViewModel?.showPrevious(); 147 this.movingIconSwapPageDelay(); 148 } else if ((moveX + this.mIconSize / 2) > this.mGridSpaceWidth && moveY < this.mGridSpaceHeight) { 149 let cachePageIndex = this.mPageDesktopViewModel?.getGridPageCount() as number; 150 if (curPageIndex === cachePageIndex - 1 && !this.mPageDesktopViewModel?.isBlankPage()) { 151 this.mPageDesktopViewModel?.addBlankPage(true); 152 } else if (curPageIndex < cachePageIndex - 1) { 153 this.mPageDesktopViewModel?.showNext(); 154 } 155 this.movingIconSwapPageDelay(); 156 } 157 } 158 159 /** 160 * Increase delay when dragging app to other page. 161 */ 162 movingIconSwapPageDelay() { 163 AppStorage.setOrCreate('isSwappingPage', true); 164 setTimeout(() => { 165 AppStorage.setOrCreate('isSwappingPage', false); 166 }, this.APP_INFO_REFRESH_DELAY); 167 } 168 169 private buildLog(item: LauncherDragItemInfo): boolean { 170 return true; 171 } 172 173 getRowEnd(item: LauncherDragItemInfo): number { 174 let result = 0; 175 if (typeof item.row !== 'undefined' && item.area?.length) { 176 result = item.row + item.area[1] - 1; 177 } 178 return result; 179 } 180 181 getColumnEnd(item: LauncherDragItemInfo): number { 182 let result = 0; 183 if (typeof item.column !== 'undefined' && item.area?.length) { 184 result = item.column + item.area[0] - 1; 185 } 186 return result; 187 } 188 189 build() { 190 Grid() { 191 ForEach(this.mAppListInfo, (item: LauncherDragItemInfo, index: number) => { 192 GridItem() { 193 if (this.buildLog(item)) { 194 } 195 if (item.typeId === CommonConstants.TYPE_APP) { 196 AppItem({ 197 item: item, 198 mPageDesktopViewModel: this.mPageDesktopViewModel, 199 mNameLines: this.mNameLines 200 }).id(`${TAG}_AppItem_${index}`) 201 } else if (item.typeId === CommonConstants.TYPE_FOLDER) { 202 FolderItem({ 203 folderItem: item, 204 mPageDesktopViewModel: this.mPageDesktopViewModel, 205 mNameLines: this.mNameLines 206 }).id(`${TAG}_FolderItem_${index}`) 207 } else if (item.typeId === CommonConstants.TYPE_CARD) { 208 FormItem({ 209 formItem: item 210 }).id(`${TAG}_FormItem_${index}`) 211 } 212 } 213 .id(`${TAG}_GridItem_${index}`) 214 .padding({ top: this.mPaddingTop }) 215 .rowStart(item.row) 216 .columnStart(item.column) 217 .rowEnd(this.getRowEnd(item)) 218 .columnEnd(this.getColumnEnd(item)) 219 .zIndex(10) 220 }, (item: LauncherDragItemInfo, index: number) => { 221 if (item.typeId === CommonConstants.TYPE_FOLDER) { 222 return JSON.stringify(item); 223 } else if (item.typeId === CommonConstants.TYPE_CARD) { 224 return JSON.stringify(item) + this.formRefresh; 225 } else if (item.typeId === CommonConstants.TYPE_APP) { 226 return JSON.stringify(item); 227 } else { 228 return ''; 229 } 230 }) 231 } 232 .id(`${TAG}_Grid_${this.swiperPage}`) 233 .columnsTemplate(this.columnsTemplate) 234 .rowsTemplate(this.rowsTemplate) 235 .columnsGap(this.mColumnsGap) 236 .rowsGap(this.mRowsGap) 237 .width(this.mGridWidth) 238 .height(this.mGridHeight) 239 .margin({ 240 right: this.mMargin, 241 left: this.mMargin 242 }) 243 .onMouse((event: MouseEvent) => { 244 if (event.button === MouseButton.Right || event.button === MouseButton.Left) { 245 AppStorage.setOrCreate('selectDesktopAppItem', ''); 246 } 247 }) 248 .onDragEnter((event: DragEvent, extraParams: string) => { 249 Log.showInfo(TAG, `onDragEnter extraParams: ${extraParams}, event: [${event.getWindowX()}, ${event.getWindowY()}]`); 250 }) 251 .onDragMove((event: DragEvent, extraParams: string) => { 252 Log.showInfo(TAG, `onDragMove event: [${event.getWindowX()}, ${event.getWindowY()}]`); 253 const dragItemInfo: LauncherDragItemInfo = AppStorage.get<LauncherDragItemInfo>('dragItemInfo') as LauncherDragItemInfo; 254 if (!dragItemInfo.isDragging) { 255 return; 256 } 257 if (AppStorage.get('deviceType') === CommonConstants.DEFAULT_DEVICE_TYPE || 258 (AppStorage.get('deviceType') !== CommonConstants.DEFAULT_DEVICE_TYPE && 259 AppStorage.get('dragItemType') === CommonConstants.DRAG_FROM_DESKTOP)) { 260 this.itemMove(event.getWindowX(), event.getWindowY()); 261 } 262 }) 263 .onDragLeave((event: DragEvent, extraParams: string) => { 264 Log.showInfo(TAG, `onDragLeave event: [${event.getWindowX()}, ${event.getWindowY()}]`); 265 }) 266 .onDrop((event: DragEvent, extraParams: string) => { 267 const dragItemType: number = AppStorage.get('dragItemType') as number; 268 Log.showInfo(TAG, `onDrop event: [${event.getWindowX()}, ${event.getWindowY()}]`); 269 if (dragItemType === CommonConstants.DRAG_FROM_DESKTOP || 270 (dragItemType === CommonConstants.DRAG_FROM_DOCK && 271 AppStorage.get('deviceType') === CommonConstants.DEFAULT_DEVICE_TYPE)) { 272 const dragResult = PageDesktopDragHandler.getInstance().onDragDrop(event.getWindowX(), event.getWindowY()); 273 Log.showInfo(TAG, `onDrop dragResult: ${dragResult}`); 274 AppStorage.setOrCreate('selectAppIndex', null); 275 const dragItemInfo: LauncherDragItemInfo = AppStorage.get('dragItemInfo') as LauncherDragItemInfo; 276 if (dragItemInfo.bundleName) { 277 BadgeManager.getInstance().updateBadgeNumber(dragItemInfo.bundleName, dragItemInfo.badgeNumber); 278 } 279 if (!dragResult) { 280 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 281 } else { 282 // Wait for the UI rendering to end. 283 setTimeout(() => { 284 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 285 }, 50); 286 } 287 } 288 }) 289 } 290}