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