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 PageDesktopViewModel.getInstance().deleteAppItem({ 86 bundleName: undefined, 87 keyName: this.appInfo.keyName 88 }); 89 } else { 90 PageDesktopViewModel.getInstance().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 PageDesktopViewModel.getInstance().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 = PageDesktopViewModel.getInstance().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: PageDesktopViewModel.getInstance().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 && 197 this.pageDesktopDragItemInfo.keyName === this.item.keyName ? 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 PageDesktopViewModel.getInstance() 215 .onAppClick(this.item.abilityName, this.item.bundleName, this.item.moduleName); 216 setTimeout(() => { 217 this.mouseClick = 0; 218 }, 300) 219 } 220 } else { 221 Log.showInfo(TAG, 'tap click'); 222 this.launchApp(); 223 } 224 }) 225 .onTouch((event: TouchEvent) => { 226 Log.showDebug(TAG, `onTouch event type: ${event.type}, x: ${event.touches[0].windowX}, y: ${event.touches[0].windowY}`); 227 if (event.type === CommonConstants.TOUCH_TYPE_UP && this.pageDesktopDragItemInfo.isDragging) { 228 let mIsDragEffectArea = 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 PageDesktopViewModel.getInstance() 247 .onAppDoubleClick(this.item.abilityName, this.item.bundleName, this.item.moduleName); 248 } 249 250 dragStart = (event: DragEvent): CustomBuilder => { 251 ContextMenu.close(); 252 this.dragItemType = CommonConstants.DRAG_FROM_DESKTOP; 253 this.item.isDragging = true; 254 this.pageDesktopDragItemInfo = this.item; 255 Log.showInfo(TAG, `pageDesktopDragItemInfo: ${JSON.stringify(this.pageDesktopDragItemInfo)}`); 256 PageDesktopDragHandler.getInstance().onDragStart(event.getWindowX(), event.getWindowY()); 257 } 258 259 /** 260 * set start app info 261 */ 262 private setStartAppInfo() { 263 Log.showInfo(TAG, `app setStartAppInfo ${this.mIconSize}`); 264 Trace.start("setStartAppInfo"); 265 const appInfo: StartAppItemInfo = { 266 bundleName: this.item.bundleName, 267 abilityName: this.item.abilityName, 268 moduleName: this.item.moduleName, 269 appIconSize: this.mIconSize, 270 appIconId: this.item.appIconId, 271 icon: ResourceManager.getInstance() 272 .getCachedAppIcon(this.item.appIconId, this.item.bundleName, this.item.moduleName), 273 row: this.item.row, 274 column: this.item.column 275 } 276 AppStorage.setOrCreate('startAppItemInfo', appInfo); 277 AppStorage.setOrCreate('startAppTypeFromPageDesktop', CommonConstants.OVERLAY_TYPE_APP_ICON); 278 this.mPageDesktopStartAppHandler.setAppIconSize(this.mIconSize); 279 this.mPageDesktopStartAppHandler.setAppIconInfo(); 280 Trace.end("setStartAppInfo"); 281 } 282}