• 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  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}