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 FolderComponent, 18} from '@ohos/common/component' 19import { 20 LauncherDragItemInfo, 21 Log, 22 Trace, 23 StyleConstants, 24 CommonConstants, 25 PresetStyleConstants, 26 AppItemInfo, 27 MenuInfo, 28 FolderData 29} from '@ohos/common'; 30import { 31 BigFolderViewModel, 32 BigFolderStyleConfig, 33 BigFolderConstants 34} from '@ohos/bigfolder'; 35import { PageDesktopDragHandler } from '../PageDesktopDragHandler'; 36import { PageDesktopViewModel } from '../../viewmodel/PageDesktopViewModel' 37import { PageDesktopStartAppHandler } from '../PageDesktopStartAppHandler'; 38import { PageDesktopGridStyleConfig } from '../PageDesktopGridStyleConfig'; 39 40const TAG = 'FolderItem'; 41 42interface FolderItemType { 43 folderId: string; 44 folderName: string; 45 enterEditing?: boolean; 46 layoutInfo: AppItemInfo[][] 47} 48 49/** 50 * Folder item, which display on desktop workspace. 51 */ 52@Component 53export default struct FolderItem { 54 @StorageLink('dragItemInfo') pageDesktopDragItemInfo: LauncherDragItemInfo = new LauncherDragItemInfo(); 55 @StorageLink('dragItemType') dragItemType: number = CommonConstants.DRAG_FROM_DESKTOP; 56 @StorageLink('openFolderStatus') openFolderStatus: number = BigFolderConstants.OPEN_FOLDER_STATUS_CLOSE; 57 @StorageLink('selectDesktopAppItem') selectDesktopAppItem: string = ''; 58 private mAppNameHeight: number = StyleConstants.DEFAULT_APP_NAME_HEIGHT; 59 private mAppNameSize: number = StyleConstants.DEFAULT_APP_NAME_SIZE; 60 private folderItem: LauncherDragItemInfo = new LauncherDragItemInfo(); 61 private isSwappingPage = false; 62 private mAppItemWidth: number = 0; 63 private mPageDesktopViewModel?: PageDesktopViewModel; 64 private mBigFolderViewModel?: BigFolderViewModel; 65 private mMargin: number = 0; 66 private mGridSpaceWidth: number = 0; 67 private mGridSpaceHeight: number = 0; 68 private mIconMarginVertical: number = StyleConstants.DEFAULT_10; 69 private mPageDesktopDragHandler: PageDesktopDragHandler = PageDesktopDragHandler.getInstance(); 70 private mPageDesktopStartAppHandler: PageDesktopStartAppHandler = PageDesktopStartAppHandler.getInstance(); 71 private mFolderStyleConfig: BigFolderStyleConfig = BigFolderViewModel.getInstance().getFolderStyleConfig(); 72 mNameLines: number = PresetStyleConstants.DEFAULT_APP_NAME_LINES; 73 74 aboutToAppear(): void { 75 this.mPageDesktopDragHandler = PageDesktopDragHandler.getInstance(); 76 this.mPageDesktopStartAppHandler = PageDesktopStartAppHandler.getInstance(); 77 this.mBigFolderViewModel = BigFolderViewModel.getInstance(); 78 this.mFolderStyleConfig = this.mBigFolderViewModel.getFolderStyleConfig(); 79 this.mPageDesktopViewModel = PageDesktopViewModel.getInstance(); 80 let styleConfig = this.mPageDesktopViewModel.getPageDesktopStyleConfig(); 81 this.mAppItemWidth = styleConfig.mIconSize; 82 this.mAppNameHeight = styleConfig.mNameHeight; 83 this.mAppNameSize = styleConfig.mNameSize; 84 this.mIconMarginVertical = styleConfig.mIconMarginVertical; 85 this.mMargin = styleConfig.mMargin; 86 this.mGridSpaceWidth = Number(this.mPageDesktopViewModel.getWorkSpaceWidth()) - this.mMargin; 87 this.mGridSpaceHeight = Number(this.mPageDesktopViewModel.getWorkSpaceHeight()); 88 this.openFolderStatus = AppStorage.get('openFolderStatus') != 'undefined' ? (AppStorage.get('openFolderStatus') as number) : BigFolderConstants.OPEN_FOLDER_STATUS_CLOSE; 89 this.formatFolderInfo(); 90 } 91 92 /** 93 * format FolderInfo 94 */ 95 private formatFolderInfo() { 96 if (typeof this.folderItem.layoutInfo === 'undefined') { 97 return; 98 } 99 let column = this.mBigFolderViewModel?.getFolderLayoutConfig().column as number; 100 let row = this.mBigFolderViewModel?.getFolderLayoutConfig().row as number; 101 const allCount = column * row; 102 if (this.folderItem.layoutInfo[0].length > allCount) { 103 let folderLayoutInfoList: AppItemInfo[][] = []; 104 let integer = Math.floor(this.folderItem.layoutInfo[0].length / allCount); 105 let remainder = this.folderItem.layoutInfo[0].length % allCount; 106 for (let i = 0; i < integer; i++) { 107 folderLayoutInfoList.push(this.folderItem.layoutInfo[0].slice(i * allCount, (i + 1) * allCount)); 108 } 109 if (remainder != 0) { 110 folderLayoutInfoList.push( 111 this.folderItem.layoutInfo[0].slice(integer * allCount, integer * allCount + remainder) 112 ); 113 } 114 this.folderItem.layoutInfo.splice(0, 1); 115 this.folderItem.layoutInfo = folderLayoutInfoList; 116 } 117 } 118 119 /** 120 * When rename is clicked, call this function to change folder state. 121 */ 122 private renameClick = () => { 123 Log.showInfo(TAG, 'click menu folder rename'); 124 AppStorage.setOrCreate('overlayMode', CommonConstants.OVERLAY_TYPE_HIDE); 125 this.mBigFolderViewModel?.openFolder(true, this.folderItem as FolderData); 126 } 127 128 private getOpenFolder(): string { 129 let openFolderData: FolderData = AppStorage.get('openFolderData') as FolderData; 130 131 return openFolderData.folderId; 132 } 133 134 dragStart = (event: DragEvent): CustomBuilder => { 135 ContextMenu.close(); 136 this.dragItemType = CommonConstants.DRAG_FROM_DESKTOP; 137 this.folderItem.isDragging = true; 138 this.pageDesktopDragItemInfo = this.folderItem; 139 const selectAppIndex = PageDesktopDragHandler.getInstance().getItemIndex(event.getWindowX(), event.getWindowY()); 140 const startPosition = PageDesktopDragHandler.getInstance().getTouchPosition(event.getWindowX(), event.getWindowY()) 141 PageDesktopDragHandler.getInstance().mStartPosition = startPosition; 142 AppStorage.setOrCreate('selectAppIndex', selectAppIndex); 143 Log.showInfo(TAG, `onDragStart event: [${event.getWindowX()}, ${event.getWindowY()}], selectAppIndex: ${selectAppIndex}`); 144 } 145 146 build() { 147 Flex({ 148 direction: FlexDirection.Column, 149 alignItems: ItemAlign.Center, 150 justifyContent: FlexAlign.SpaceAround 151 }) { 152 Column() { 153 FolderComponent({ 154 showFolderName: true, 155 mFolderItem: this.folderItem, 156 badgeNumber: this.folderItem.badgeNumber, 157 isSelect: this.selectDesktopAppItem === this.folderItem.folderId, 158 folderNameHeight: this.mAppNameHeight, 159 folderNameLines: this.mNameLines, 160 folderNameSize: this.mAppNameSize, 161 folderGridSize:this.mFolderStyleConfig.mGridSize, 162 appIconSize: this.mFolderStyleConfig.mFolderAppSize, 163 gridMargin:this.mFolderStyleConfig.mGridMargin, 164 mPaddingTop: this.mIconMarginVertical, 165 gridGap:this.mFolderStyleConfig.mFolderGridGap, 166 iconNameMargin: this.mFolderStyleConfig.mIconNameMargin, 167 nameFontColor: this.mPageDesktopViewModel?.getPageDesktopStyleConfig().mNameFontColor as string, 168 onAppIconClick: (event: ClickEvent, appItem: AppItemInfo) => { 169 Log.showInfo(TAG, 'onAppIconClick'); 170 Trace.start(Trace.CORE_METHOD_START_APP_ANIMATION); 171 this.setStartAppInfo(appItem); 172 this.mPageDesktopViewModel?.openApplication(appItem.abilityName, appItem.bundleName, appItem.moduleName); 173 }, 174 onOpenFolderClick: (event: ClickEvent, folderItem: FolderData) => { 175 Log.showInfo(TAG, 'onOpenFolderClick'); 176 Trace.start(Trace.CORE_METHOD_OPEN_FOLDER); 177 this.mBigFolderViewModel?.openFolder(false, folderItem); 178 }, 179 onFolderTouch: (event: TouchEvent, folderItem: FolderData) => { 180 if (event.type === CommonConstants.TOUCH_TYPE_UP && this.pageDesktopDragItemInfo.isDragging) { 181 let mIsDragEffectArea = 182 PageDesktopDragHandler.getInstance().isDragEffectArea(event.touches[0].windowX, event.touches[0].windowY); 183 Log.showInfo(TAG, `onTouch mIsDragEffectArea: ${mIsDragEffectArea}`); 184 if (!mIsDragEffectArea) { 185 PageDesktopDragHandler.getInstance().deleteBlankPageOutsideEffect(); 186 AppStorage.setOrCreate<LauncherDragItemInfo>('dragItemInfo', new LauncherDragItemInfo()); 187 AppStorage.setOrCreate('selectAppIndex', null); 188 } 189 } 190 }, 191 onGetPosition: (getPosition: Function) => { 192 Log.showInfo(TAG, 'onGetPosition'); 193 let styleConfig = this.mPageDesktopViewModel?.getPageDesktopStyleConfig() as PageDesktopGridStyleConfig; 194 let row = this.folderItem.row as number; 195 let column = this.folderItem.column as number; 196 Log.showInfo(TAG, `onGetPosition currentFolderPosition row: ${row}, column: ${column}`); 197 let x = styleConfig.mAppItemSize * column + 198 styleConfig.mColumnsGap * column + styleConfig.mMargin + styleConfig.mIconMarginHorizontal; 199 let y = styleConfig.mAppItemSize * row + 200 styleConfig.mRowsGap * row + styleConfig.mDesktopMarginTop + styleConfig.mIconMarginVertical; 201 Log.showInfo(TAG, `onGetPosition currentFolderPosition x: ${x}, y: ${y}`); 202 getPosition(x, y); 203 }, 204 buildMenu: (folderItem: LauncherDragItemInfo) => { 205 return this.mPageDesktopViewModel?.buildRenameMenuInfoList(folderItem, this.renameClick) as MenuInfo[]; 206 }, 207 dragStart: this.dragStart 208 }) 209 } 210 .visibility((this.pageDesktopDragItemInfo.folderId === 211 this.folderItem.folderId || (this.openFolderStatus != 0 && this.getOpenFolder() == 212 this.folderItem.folderId)) ? Visibility.Hidden : Visibility.Visible) 213 .onMouse((event: MouseEvent) => { 214 if (event.button == MouseButton.Right) { 215 event.stopPropagation(); 216 Log.showInfo(TAG, 'onMouse mouse button right'); 217 AppStorage.setOrCreate('selectDesktopAppItem', this.folderItem.folderId); 218 } 219 }) 220 .gesture( 221 GestureGroup(GestureMode.Exclusive, 222 TapGesture({ count: 2 }) 223 .onAction((event: GestureEvent) => { 224 Log.showInfo(TAG, 'TapGesture double click'); 225 this.mBigFolderViewModel?.openFolder(false, this.folderItem as FolderData); 226 }) 227 ) 228 ) 229 } 230 .parallelGesture(LongPressGesture({ repeat: false })) 231 .width(StyleConstants.PERCENTAGE_100) 232 .height(StyleConstants.PERCENTAGE_100) 233 } 234 235 /** 236 * set start app info 237 */ 238 private setStartAppInfo(appItem: AppItemInfo) { 239 AppStorage.setOrCreate('startAppItemInfo', appItem); 240 AppStorage.setOrCreate('startAppFromFolderItemInfo', this.folderItem); 241 AppStorage.setOrCreate('startAppTypeFromPageDesktop', CommonConstants.OVERLAY_TYPE_FOLDER); 242 this.mPageDesktopStartAppHandler.setAppIconSize(this.mFolderStyleConfig.mFolderAppSize); 243 this.mPageDesktopStartAppHandler.setAppIconInfo(); 244 } 245}