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 '../utils/Log';
17import { MenuInfo } from '../bean/MenuInfo';
18import { StyleConstants } from '../constants/StyleConstants';
19import { CommonConstants } from '../constants/CommonConstants';
20import { ResourceManager } from '../manager/ResourceManager';
21
22const TAG = 'AppMenu';
23
24@Component
25export struct AppMenu {
26  menuInfoList: Array<MenuInfo> = [];
27  getMenuInfoList?: Function;
28  menuMode: number = CommonConstants.MENU_UI_MODE_LIGHT;
29  fixedMenuList: Array<MenuInfo> = [];
30  dynamicMenuList: Array<MenuInfo> = [];
31  isBothTypeMenuExist: boolean = true;
32  closeMenu: Function = () => {};
33
34  aboutToAppear(): void {
35    Log.showInfo(TAG, 'aboutToAppear start');
36    if (this.getMenuInfoList) {
37      this.menuInfoList = this.getMenuInfoList();
38    }
39    this.fixedMenuList = [];
40    this.dynamicMenuList = [];
41    for (let menuInfo of this.menuInfoList) {
42      if (menuInfo.menuType == CommonConstants.MENU_TYPE_FIXED) {
43        this.fixedMenuList.push(menuInfo);
44      } else {
45        this.dynamicMenuList.push(menuInfo);
46      }
47    }
48    this.isBothTypeMenuExist = this.fixedMenuList.length > 0 && this.dynamicMenuList.length > 0;
49  }
50
51  aboutToDisappear(): void {
52    Log.showInfo(TAG, 'aboutToDisappear start');
53    this.fixedMenuList = [];
54    this.dynamicMenuList = [];
55  }
56
57  build() {
58    Column() {
59      Column() {
60        ForEach(this.dynamicMenuList, (item: MenuInfo) => {
61          Column() {
62            HorizontalMenuItem({
63              menuInfo: item,
64              menuMode: this.menuMode,
65              closeMenu: this.closeMenu
66            })
67          }
68        }, (item: MenuInfo) => JSON.stringify(item))
69      }
70      .visibility(this.dynamicMenuList.length > 0 ? Visibility.Visible : Visibility.None)
71
72      if (this.isBothTypeMenuExist) {
73        Divider()
74          .vertical(false)
75          .color((this.menuMode == CommonConstants.MENU_UI_MODE_LIGHT) ? '#33000000' : '#33ffffff')
76          .strokeWidth(1)
77      }
78
79      Column() {
80        ForEach(this.fixedMenuList, (item: MenuInfo) => {
81          Column() {
82            HorizontalMenuItem({
83              menuInfo: item,
84              menuMode: this.menuMode,
85              closeMenu: this.closeMenu
86            })
87          }
88        }, (item: MenuInfo) => JSON.stringify(item))
89      }
90      .visibility(this.fixedMenuList.length > 0 ? Visibility.Visible : Visibility.None)
91    }
92    .padding({
93      top: 4,
94      bottom: 4,
95      left: 4,
96      right: 4
97    })
98    .borderRadius(StyleConstants.DEFAULT_12)
99  }
100}
101
102@Component
103struct HorizontalMenuItem {
104  @State shortcutIcon: string = StyleConstants.DEFAULT_ICON;
105  @State shortcutName: string = '';
106  private mResourceManager = ResourceManager.getInstance();
107  menuInfo: MenuInfo = new MenuInfo();
108  menuMode: number = CommonConstants.MENU_UI_MODE_LIGHT;
109  closeMenu: Function = () => {};
110
111  aboutToAppear(): void {
112    this.mResourceManager = ResourceManager.getInstance();
113    this.updateIcon();
114    this.updateName();
115  }
116
117  aboutToDisappear(): void {
118  }
119
120  public shortcutIconLoadCallback = (image: string) => {
121    this.shortcutIcon = image;
122  }
123
124  public shortcutNameLoadCallback = (name: string) => {
125    this.shortcutName = name;
126  }
127
128  public updateIcon() {
129    if (this.menuInfo.shortcutIconId != -1 && this.menuInfo.menuImgSrc != '' && this.menuInfo.menuImgSrc != null) {
130      this.mResourceManager.getAppIconWithCache(this.menuInfo.shortcutIconId, this.menuInfo.bundleName,
131        this.menuInfo.moduleName, this.shortcutIconLoadCallback, StyleConstants.DEFAULT_ICON);
132    } else {
133      this.shortcutIconLoadCallback(this.menuInfo.menuImgSrc);
134    }
135  }
136
137  public updateName() {
138    if (this.menuInfo.shortcutLabelId != -1 && this.menuInfo.menuText != '' && this.menuInfo.menuText != null && this.mResourceManager) {
139      this.mResourceManager.getAppNameWithCache(this.menuInfo.shortcutLabelId, this.menuInfo.bundleName,
140        this.menuInfo.moduleName, this.shortcutName, this.shortcutNameLoadCallback);
141    } else {
142      this.shortcutNameLoadCallback(this.menuInfo.menuText);
143    }
144  }
145
146  build() {
147    Row() {
148      if (this.shortcutIcon != null && this.shortcutIcon != '') {
149        Image(this.shortcutIcon)
150          .objectFit(ImageFit.Contain)
151          .height(StyleConstants.DEFAULT_20)
152          .width(StyleConstants.DEFAULT_20)
153          .margin({
154            left: 12
155          })
156      } else {
157        Image('')
158          .objectFit(ImageFit.Contain)
159          .height(StyleConstants.DEFAULT_20)
160          .width(StyleConstants.DEFAULT_20)
161          .backgroundColor('#33ffffFF')
162          .margin({
163            left: 12
164          })
165      }
166      Text(this.shortcutName)
167        .fontColor((this.menuMode == CommonConstants.MENU_UI_MODE_LIGHT) ? '#e5000000' : '#e5ffffff')
168        .fontSize(14)
169        .height(StyleConstants.DEFAULT_20)
170        .margin({
171          left: StyleConstants.DEFAULT_8
172        })
173        .textOverflow({overflow: TextOverflow.Ellipsis})
174    }
175    .alignItems(VerticalAlign.Center)
176    .borderRadius(StyleConstants.DEFAULT_ITEM_RADIUS)
177    .height(StyleConstants.DEFAULT_40)
178    .width(235)
179    .onClick(() => {
180      this.menuInfo?.onMenuClick();
181      this.closeMenu();
182    })
183  }
184}