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