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 CardItemInfo, 24 FolderData, 25 BadgeManager 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"; 35const APP_INFO_REFRESH_DELAY = 1000; 36 37interface AppListInfo { 38 appGridInfo: LauncherDragItemInfo[][] 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 74 private updateAppListInfo(): void { 75 this.mAppListInfo = this.appListInfo.appGridInfo[this.swiperPage]; 76 this.updateOpenFolderData(); 77 } 78 79 /** 80 * 监听桌面元素变化时,更新打开的大文件的数据。 81 * eg:应用角标更新时,大文件内的应用角标同步更新。 82 */ 83 updateOpenFolderData() { 84 const openFolderData = AppStorage.get('openFolderData') as FolderData; 85 if (openFolderData?.folderId && this.mAppListInfo?.length) { 86 let temp = this.mAppListInfo.find((item: LauncherDragItemInfo) => item?.folderId === openFolderData.folderId); 87 AppStorage.setOrCreate('openFolderData', temp as FolderData); 88 } 89 } 90 91 aboutToAppear(): void { 92 Log.showInfo(TAG, 'aboutToAppear'); 93 this.mPageDesktopViewModel = PageDesktopViewModel.getInstance(); 94 this.updateDeskTopScreen(); 95 } 96 97 updateDeskTopScreen(): void { 98 Log.showInfo(TAG, 'updateDeskTopScreen'); 99 this.mPageDesktopStyleConfig = PageDesktopViewModel.getInstance().getPageDesktopStyleConfig() as PageDesktopGridStyleConfig; 100 this.mMargin = this.mPageDesktopStyleConfig.mMargin; 101 this.mColumnsGap = this.mPageDesktopStyleConfig.mColumnsGap; 102 this.mRowsGap = this.mPageDesktopStyleConfig.mRowsGap; 103 this.mPaddingTop = this.mPageDesktopStyleConfig.mPaddingTop; 104 this.mNameLines = this.mPageDesktopStyleConfig.mNameLines; 105 this.mMarginTop = this.mPageDesktopStyleConfig.mDesktopMarginTop; 106 this.mGridWidth = this.mPageDesktopStyleConfig.mGridWidth; 107 this.mGridHeight = this.mPageDesktopStyleConfig.mGridHeight; 108 this.mIconSize = this.mPageDesktopStyleConfig.mIconSize; 109 this.mGridSpaceWidth = Number(PageDesktopViewModel.getInstance().getWorkSpaceWidth()) - this.mMargin; 110 this.mGridSpaceHeight = Number(PageDesktopViewModel.getInstance().getWorkSpaceHeight()); 111 this.changeConfig(); 112 localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null); 113 } 114 115 private changeColumnAndRow(): void { 116 this.changeConfig(); 117 } 118 119 private changeConfig(): void { 120 let mGridConfig = PageDesktopViewModel.getInstance().getGridConfig() as GridLayout; 121 let column = mGridConfig.column as number; 122 let row = mGridConfig.row as number; 123 this.ColumnsTemplate = ''; 124 this.RowsTemplate = ''; 125 for (let i = 0;i < column; i++) { 126 this.ColumnsTemplate += '1fr ' 127 } 128 for (let i = 0;i < row; i++) { 129 this.RowsTemplate += '1fr ' 130 } 131 } 132 133 itemMove(moveX: number, moveY: number): void { 134 const isSwappingPage: boolean = AppStorage.get('isSwappingPage') as boolean; 135 if (isSwappingPage) { 136 return; 137 } 138 let curPageIndex: number = AppStorage.get('pageIndex') as number; 139 if ((moveX - this.mIconSize / 2) < this.mMargin && curPageIndex > 0 && moveY < this.mGridSpaceHeight) { 140 PageDesktopViewModel.getInstance().showPrevious(); 141 this.movingIconSwapPageDelay(); 142 } else if ((moveX + this.mIconSize / 2) > this.mGridSpaceWidth && moveY < this.mGridSpaceHeight) { 143 let cachePageIndex = PageDesktopViewModel.getInstance().getGridPageCount() as number; 144 if (curPageIndex === cachePageIndex - 1 && !PageDesktopViewModel.getInstance().isBlankPage()) { 145 PageDesktopViewModel.getInstance().addBlankPage(true); 146 } else if(curPageIndex < cachePageIndex - 1) { 147 PageDesktopViewModel.getInstance().showNext(); 148 } 149 this.movingIconSwapPageDelay(); 150 } 151 } 152 153 /** 154 * Increase delay when dragging app to other page. 155 */ 156 movingIconSwapPageDelay() { 157 AppStorage.setOrCreate('isSwappingPage', true); 158 setTimeout(() => { 159 AppStorage.setOrCreate('isSwappingPage', false); 160 }, APP_INFO_REFRESH_DELAY); 161 } 162 163 private buildLog(item: LauncherDragItemInfo): boolean { 164 return true; 165 } 166 167 getRowEnd(item: LauncherDragItemInfo): number { 168 let result = 0; 169 if (typeof item.row !== 'undefined' && item.area?.length) { 170 result = item.row + item.area[1] - 1; 171 } 172 return result; 173 } 174 175 getColumnEnd(item: LauncherDragItemInfo): number { 176 let result = 0; 177 if (typeof item.column !== 'undefined' && item.area?.length) { 178 result = item.column + item.area[0] - 1; 179 } 180 return result; 181 } 182 183 build() { 184 Grid() { 185 ForEach(this.mAppListInfo, (item: LauncherDragItemInfo, index: number) => { 186 GridItem() { 187 if (this.buildLog(item)) { 188 } 189 if (item.typeId === CommonConstants.TYPE_APP) { 190 AppItem({ 191 item: item, 192 mPageDesktopViewModel: this.mPageDesktopViewModel, 193 mNameLines: this.mNameLines 194 }).id(`${TAG}_AppItem_${index}`) 195 } else if (item.typeId === CommonConstants.TYPE_FOLDER) { 196 FolderItem({ 197 folderItem: item, 198 mPageDesktopViewModel: this.mPageDesktopViewModel, 199 mNameLines: this.mNameLines 200 }).id(`${TAG}_FolderItem_${index}`) 201 } else if (item.typeId === CommonConstants.TYPE_CARD) { 202 FormItem({ 203 formItem: item 204 }).id(`${TAG}_FormItem_${index}`) 205 } 206 } 207 .id(`${TAG}_GridItem_${index}`) 208 .padding({ top: this.mPaddingTop }) 209 .rowStart(item.row) 210 .columnStart(item.column) 211 .rowEnd(this.getRowEnd(item)) 212 .columnEnd(this.getColumnEnd(item)) 213 .zIndex(10) 214 }, (item: LauncherDragItemInfo, index: number) => { 215 if (item.typeId === CommonConstants.TYPE_FOLDER) { 216 return JSON.stringify(item); 217 } else if (item.typeId === CommonConstants.TYPE_CARD) { 218 return JSON.stringify(item) + this.formRefresh; 219 } else if (item.typeId === CommonConstants.TYPE_APP) { 220 return JSON.stringify(item); 221 } else { 222 return ''; 223 } 224 }) 225 } 226 .id(`${TAG}_Grid_${this.swiperPage}`) 227 .columnsTemplate(this.ColumnsTemplate) 228 .rowsTemplate(this.RowsTemplate) 229 .columnsGap(this.mColumnsGap) 230 .rowsGap(this.mRowsGap) 231 .width(this.mGridWidth) 232 .height(this.mGridHeight) 233 .margin({ 234 right: this.mMargin, 235 left: this.mMargin 236 }) 237 .onMouse((event: MouseEvent) => { 238 if (event.button === MouseButton.Right || event.button === MouseButton.Left) { 239 AppStorage.setOrCreate('selectDesktopAppItem', ''); 240 } 241 }) 242 .onDragEnter((event: DragEvent, extraParams: string) => { 243 Log.showInfo(TAG, `onDragEnter extraParams: ${extraParams}, event: [${event.getWindowX()}, ${event.getWindowY()}]`); 244 }) 245 .onDragMove((event: DragEvent, extraParams: string) => { 246 Log.showInfo(TAG, `onDragMove event: [${event.getWindowX()}, ${event.getWindowY()}]`); 247 const dragItemInfo: LauncherDragItemInfo = AppStorage.get<LauncherDragItemInfo>('dragItemInfo') as LauncherDragItemInfo; 248 if (!dragItemInfo.isDragging) return; 249 if (AppStorage.get('deviceType') === CommonConstants.DEFAULT_DEVICE_TYPE 250 || (AppStorage.get('deviceType') !== CommonConstants.DEFAULT_DEVICE_TYPE 251 && AppStorage.get('dragItemType') === CommonConstants.DRAG_FROM_DESKTOP)) { 252 this.itemMove(event.getWindowX(), event.getWindowY()); 253 } 254 }) 255 .onDragLeave((event: DragEvent, extraParams: string) => { 256 Log.showInfo(TAG, `onDragLeave event: [${event.getWindowX()}, ${event.getWindowY()}]`); 257 }) 258 .onDrop((event: DragEvent, extraParams: string) => { 259 const dragItemType: number = AppStorage.get('dragItemType') as number; 260 Log.showInfo(TAG, `onDrop event: [${event.getWindowX()}, ${event.getWindowY()}]`); 261 if (dragItemType === CommonConstants.DRAG_FROM_DESKTOP || 262 (dragItemType === CommonConstants.DRAG_FROM_DOCK && 263 AppStorage.get('deviceType') === CommonConstants.DEFAULT_DEVICE_TYPE)) { 264 const dragResult = PageDesktopDragHandler.getInstance().onDragDrop(event.getWindowX(), event.getWindowY()); 265 Log.showInfo(TAG, `onDrop dragResult: ${dragResult}`); 266 AppStorage.setOrCreate('selectAppIndex', null); 267 const dragItemInfo: LauncherDragItemInfo = AppStorage.get('dragItemInfo') as LauncherDragItemInfo; 268 if (dragItemInfo.bundleName) { 269 BadgeManager.getInstance().updateBadgeNumber(dragItemInfo.bundleName, dragItemInfo.badgeNumber); 270 } 271 if (!dragResult) { 272 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 273 } else { 274 // Wait for the UI rendering to end. 275 setTimeout(() => { 276 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 277 }, 50); 278 } 279 } 280 }) 281 } 282}