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 AppBubble, 18 UninstallDialog, 19 FormManagerDialog 20} from '@ohos/common/component' 21import { 22 AppItemInfo, 23 CardItemInfo, 24 LauncherDragItemInfo, 25 Log, 26 Trace, 27 StyleConstants, 28 PresetStyleConstants, 29 ResourceManager, 30 CommonConstants, 31 MenuInfo 32} from '@ohos/common'; 33import { PageDesktopDragHandler } from '../PageDesktopDragHandler'; 34import { PageDesktopViewModel } from '../../viewmodel/PageDesktopViewModel'; 35import { PageDesktopStartAppHandler } from '../PageDesktopStartAppHandler'; 36 37const DOUBLE_CLICK_COUNT = 2 38 39const TAG = 'AppItem'; 40 41interface StartAppItemInfo { 42 bundleName?: string; 43 abilityName?: string; 44 moduleName?: string; 45 appIconSize: number; 46 appIconId?: number; 47 icon: ResourceStr; 48 row?: number; 49 column?: number; 50} 51 52@Component 53export default struct AppItem { 54 @StorageLink('dragItemInfo') pageDesktopDragItemInfo: LauncherDragItemInfo = new LauncherDragItemInfo(); 55 @StorageLink('dragItemType') dragItemType: number = CommonConstants.DRAG_FROM_DESKTOP; 56 @StorageLink('uninstallAppInfo') appInfo: AppItemInfo = new AppItemInfo(); 57 @StorageLink('formAppInfo') formAppInfo: CardItemInfo = new CardItemInfo(); 58 @StorageLink('selectDesktopAppItem') selectDesktopAppItem: string = ''; 59 @State mAppNameHeight: number = StyleConstants.DEFAULT_APP_NAME_HEIGHT; 60 @State mAppItemWidth: number = StyleConstants.DEFAULT_APP_ITEM_WIDTH; 61 @State mAppNameSize: number = StyleConstants.DEFAULT_APP_NAME_SIZE; 62 mNameLines: number = PresetStyleConstants.DEFAULT_APP_NAME_LINES; 63 @State mIconSize: number = StyleConstants.DEFAULT_APP_ICON_SIZE_WIDTH; 64 mIconNameMargin: number = PresetStyleConstants.DEFAULT_ICON_NAME_GAP; 65 private mMargin: number = 0; 66 private mMarginVertical: number = 0; 67 private mGridSpaceWidth : number = 0; 68 private mGridSpaceHeight : number = 0; 69 private isSwappingPage = false; 70 private item: LauncherDragItemInfo = new LauncherDragItemInfo(); 71 private mPageDesktopViewModel?: PageDesktopViewModel; 72 private isPad: boolean = false; 73 private mPageDesktopDragHandler: PageDesktopDragHandler = PageDesktopDragHandler.getInstance(); 74 private mPageDesktopStartAppHandler: PageDesktopStartAppHandler = PageDesktopStartAppHandler.getInstance(); 75 private mouseClick: number = 0; 76 private dialogName: string = ''; 77 private clearForm = () => {}; 78 79 dialogController: CustomDialogController | null = new CustomDialogController({ 80 builder: UninstallDialog({ 81 cancel: () => {}, 82 confirm: () => { 83 if (this.isPad) { 84 this.mPageDesktopViewModel?.deleteAppItem({ 85 bundleName: undefined, 86 keyName: this.appInfo.keyName 87 }); 88 } else { 89 this.mPageDesktopViewModel?.uninstallApp(this.appInfo.bundleName, this.appInfo.isUninstallAble); 90 } 91 }, 92 dialogName: this.dialogName, 93 dialogContent: this.appInfo.appName + ' ?', 94 }), 95 cancel: this.cancelDialog, 96 autoCancel: false, 97 customStyle: true 98 }); 99 100 /** 101 * Dialog for form manager view (pad adaptation). 102 */ 103 formManagerDialogController: CustomDialogController | null = new CustomDialogController({ 104 builder: FormManagerDialog({ 105 cancel: (callback?: () => void) => { 106 // delete all form 107 if (callback != undefined) { 108 this.clearForm = callback; 109 } 110 }, 111 confirm: (formCardItem: CardItemInfo) => { 112 // add form to desktop 113 Log.showInfo(TAG, `createCardToDeskTop formCardItem: ${JSON.stringify(formCardItem)}`); 114 this.mPageDesktopViewModel?.createCardToDeskTop(formCardItem); 115 // delete other form 116 }, 117 bundleName: this.formAppInfo.bundleName, 118 appName: this.formAppInfo.appName, 119 appLabelId: this.formAppInfo.appLabelId 120 }), 121 cancel: this.cancelFormDialog, 122 autoCancel: false, 123 customStyle: true 124 }); 125 126 /** 127 * When click cancel dialog, this function will be called. 128 */ 129 cancelFormDialog() { 130 Log.showInfo(TAG, 'cancel form dialog'); 131 this.clearForm(); 132 } 133 134 aboutToAppear(): void { 135 this.mPageDesktopViewModel = PageDesktopViewModel.getInstance(); 136 this.mPageDesktopDragHandler = PageDesktopDragHandler.getInstance(); 137 this.mPageDesktopStartAppHandler = PageDesktopStartAppHandler.getInstance(); 138 this.isPad = this.mPageDesktopViewModel.getDevice(); 139 let styleConfig = this.mPageDesktopViewModel.getPageDesktopStyleConfig(); 140 this.mAppNameHeight = styleConfig.mNameHeight; 141 this.mAppItemWidth = styleConfig.mAppItemSize; 142 this.mAppNameSize = styleConfig.mNameSize; 143 this.mMargin = styleConfig.mMargin; 144 this.mIconSize = styleConfig.mIconSize; 145 this.mMarginVertical = styleConfig.mIconMarginVertical; 146 this.mIconNameMargin = styleConfig.mIconNameMargin; 147 this.mGridSpaceWidth = Number(this.mPageDesktopViewModel.getWorkSpaceWidth()) - this.mMargin; 148 this.mGridSpaceHeight = Number(this.mPageDesktopViewModel.getWorkSpaceHeight()); 149 ResourceManager.getInstance().getStringByResource(this.isPad 150 ? $r('app.string.is_delete_form') : $r('app.string.isUninstall')).then((resName) => { 151 this.dialogName = resName; 152 }); 153 } 154 155 aboutToDisappear(): void { 156 this.dialogController = null; 157 this.formManagerDialogController = null; 158 } 159 160 getMenuInfoList = (): MenuInfo[] => { 161 const menuInfo = this.mPageDesktopViewModel?.buildMenuInfoList(this.item, 162 this.dialogController, this.formManagerDialogController) as MenuInfo[]; 163 return menuInfo; 164 } 165 166 /** 167 * When click cancel dialog, this function will be called. 168 */ 169 cancelDialog() { 170 Log.showInfo(TAG, 'cancel app uninstall dialog'); 171 } 172 173 build() { 174 Column() { 175 AppBubble({ 176 iconSize: this.mIconSize, 177 nameSize: this.mAppNameSize, 178 nameHeight: this.mAppNameHeight, 179 nameFontColor: this.mPageDesktopViewModel?.getPageDesktopStyleConfig().mNameFontColor as string, 180 appName: this.item.appName, 181 bundleName: this.item.bundleName, 182 abilityName: this.item.abilityName, 183 moduleName: this.item.moduleName, 184 appIconId: this.item.appIconId, 185 appLabelId: this.item.appLabelId, 186 badgeNumber: this.item.badgeNumber, 187 isSelect: this.selectDesktopAppItem == this.item.keyName, 188 getMenuInfoList: this.getMenuInfoList, 189 mPaddingTop: this.mMarginVertical, 190 nameLines: this.mNameLines, 191 mIconNameMargin: this.mIconNameMargin, 192 dragStart: this.dragStart 193 }) 194 } 195 .visibility(this.dragItemType === 196 CommonConstants.DRAG_FROM_DESKTOP && this.pageDesktopDragItemInfo.keyName === this.item.keyName ? 197 Visibility.None : Visibility.Visible) 198 .onMouse((event: MouseEvent) => { 199 if (event.button == MouseButton.Right) { 200 event.stopPropagation(); 201 Log.showInfo(TAG, 'onMouse mouse button right'); 202 AppStorage.setOrCreate('selectDesktopAppItem', this.item.keyName); 203 } 204 }) 205 .onClick((event) => { 206 Log.showInfo(TAG, `tap action ${JSON.stringify(event)}`); 207 if (event.source == SourceType.Mouse) { 208 this.mouseClick++; 209 if (this.mouseClick == DOUBLE_CLICK_COUNT) { 210 Log.showInfo(TAG, 'mouse double click'); 211 this.mouseClick = 0; 212 this.launchApp(); 213 } else { 214 this.mPageDesktopViewModel?.onAppClick(this.item.abilityName, this.item.bundleName, this.item.moduleName); 215 setTimeout(() => { 216 this.mouseClick = 0; 217 }, 300) 218 } 219 } else { 220 Log.showInfo(TAG, 'tap click'); 221 this.launchApp(); 222 } 223 }) 224 .onTouch((event: TouchEvent) => { 225 Log.showDebug(TAG, `onTouch event type: ${event.type}, x: ${event.touches[0].windowX}, y: ${event.touches[0].windowY}`); 226 if (event.type === CommonConstants.TOUCH_TYPE_UP && this.pageDesktopDragItemInfo.isDragging) { 227 let mIsDragEffectArea = 228 PageDesktopDragHandler.getInstance().isDragEffectArea(event.touches[0].windowX, event.touches[0].windowY); 229 Log.showInfo(TAG, `onTouch mIsDragEffectArea: ${mIsDragEffectArea}`); 230 if (!mIsDragEffectArea) { 231 this.pageDesktopDragItemInfo = new LauncherDragItemInfo(); 232 AppStorage.setOrCreate('selectAppIndex', null); 233 } 234 } 235 }) 236 .width(this.mAppItemWidth) 237 .height(this.mAppItemWidth) 238 } 239 240 /** 241 * When app is double clicked, call this method. 242 */ 243 private launchApp() { 244 Trace.start(Trace.CORE_METHOD_START_APP_ANIMATION); 245 this.setStartAppInfo(); 246 this.mPageDesktopViewModel?.onAppDoubleClick(this.item.abilityName, this.item.bundleName, this.item.moduleName); 247 } 248 249 dragStart = (event: DragEvent): CustomBuilder => { 250 ContextMenu.close(); 251 this.dragItemType = CommonConstants.DRAG_FROM_DESKTOP; 252 this.item.isDragging = true; 253 this.pageDesktopDragItemInfo = this.item; 254 Log.showInfo(TAG, `pageDesktopDragItemInfo: ${JSON.stringify(this.pageDesktopDragItemInfo)}`); 255 PageDesktopDragHandler.getInstance().onDragStart(event.getWindowX(), event.getWindowY()); 256 } 257 258 /** 259 * set start app info 260 */ 261 private setStartAppInfo() { 262 Log.showInfo(TAG, `app setStartAppInfo ${this.mIconSize}`); 263 Trace.start('setStartAppInfo'); 264 const appInfo: StartAppItemInfo = { 265 bundleName: this.item.bundleName, 266 abilityName: this.item.abilityName, 267 moduleName: this.item.moduleName, 268 appIconSize: this.mIconSize, 269 appIconId: this.item.appIconId, 270 icon: ResourceManager.getInstance() 271 .getCachedAppIcon(this.item.appIconId, this.item.bundleName, this.item.moduleName), 272 row: this.item.row, 273 column: this.item.column 274 } 275 AppStorage.setOrCreate('startAppItemInfo', appInfo); 276 AppStorage.setOrCreate('startAppTypeFromPageDesktop', CommonConstants.OVERLAY_TYPE_APP_ICON); 277 this.mPageDesktopStartAppHandler.setAppIconSize(this.mIconSize); 278 this.mPageDesktopStartAppHandler.setAppIconInfo(); 279 Trace.end('setStartAppInfo'); 280 } 281}