• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}