• 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 {isNfcAvailable} from '../../../../../../../../common/src/main/ets/default/Constants';
17import Log from '../../../../../../../../common/src/main/ets/default/Log'
18import { StatusBarData, StatusBarBackgroundData, StatusBarConfig } from '../common/Constants'
19import { FASlotName } from '../../../../../../../../common/src/main/ets/default/Constants'
20import { TintContentInfo } from '../../../../../../../../common/src/main/ets/default/TintStateManager'
21import StyleConfigurationCommon, { CommonStyle
22} from '../../../../../../../../common/src/main/ets/default/StyleConfiguration'
23import StyleConfiguration, { StatusBarNotificationIconStyle, VerticalStatusBarItemLoadComponentStyle
24} from '../common/StyleConfiguration'
25import ViewModel from '../viewmodel/StatusBarVM'
26import { StringArray } from '../viewmodel/StatusBarVM'
27import IconItemComponent from './IconItemComponent'
28import BatteryIcon from '../../../../../../../batterycomponent/src/main/ets/default/pages/batteryIcon'
29import ClockIcon from '../../../../../../../clockcomponent/src/main/ets/default/pages/clockIcon'
30import AirplaneIcon from '../../../../../../../airplanecomponent/src/main/ets/default/pages/StatusBarIconItemAirplaneComponent'
31import WifiIcon from '../../../../../../../wificomponent/src/main/ets/default/pages/wifiIcon'
32import BluetoothIcon from '../../../../../../../bluetoothcomponent/src/main/ets/com/ohos/pages/StatusBarIconItemBluetoothComponent'
33import SignalIcon from '../../../../../../../signalcomponent/src/main/ets/default/pages/signalIcon'
34import CapsuleIcon from '../../../../../../../capsulecomponent/src/main/ets/default/pages/CapsuleIcon'
35import LocationIcon from '../../../../../../../locationcomponent/src/main/ets/com/ohos/pages/StatusBarIconItemLocationComponent'
36import RingModeIcon from '../../../../../../../ringmodecomponent/src/main/ets/com/ohos/pages/StatusBarIconItemRingModeComponent'
37import NfcIcon from '../../../../../../../nfccomponent/src/main/ets/com/ohos/pages/StatusBarIconItemNFComponent'
38import { NotificationItemData } from '@ohos/common';
39import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';
40
41const TAG = 'StatusBarComponent'
42const TAG_StatusBarGroup = 'StatusBarGroup'
43const TAG_VerticalStatusBarItemLoadComponent = 'VerticalStatusBarItemLoadComponent'
44const TAG_StatusBarItemLoadComponent = 'StatusBarItemLoadComponent'
45const TAG_StatusBarEmptyIcon = 'StatusBarEmptyIcon'
46const TAG_StatusBarNotificationIcon = 'StatusBarNotificationIcon'
47const TAG_StatusBarBackground = 'StatusBarBackground'
48
49interface Item {
50  index: number;
51  data: NotificationItemData[];
52}
53
54@Component
55export default struct StatusBarComponent {
56  private mStatusBarComponentConfig: StatusBarConfig | undefined = undefined
57  @State mStatusBarData: StatusBarData = ViewModel.getStatusBarData()
58  private moduleName: string = ''
59
60  aboutToAppear() {
61    AppStorage.SetOrCreate('size', $r("app.float.status_bar_margin_left_right"));
62    Log.showInfo(TAG, `aboutToAppear Start, mStatusBarComponentConfig: ${JSON.stringify(this.mStatusBarComponentConfig)}`);
63    this.initViewModel(this.moduleName);
64  }
65
66  aboutToDisappear() {
67    Log.showInfo(TAG, `aboutToDisappear`);
68  }
69
70  initViewModel(moduleName: string) {
71    Log.showInfo(TAG, `initViewModel`);
72    ViewModel.initViewModel(this.mStatusBarComponentConfig, moduleName);
73  }
74
75  build() {
76    Stack() {
77      StatusBarBackground()
78      if (this.mStatusBarData.showHorizontal) {
79        Row() {
80          StatusBarGroup({
81            index: 0,
82            mLayoutWeight: 1,
83            mAlignItems: HorizontalAlign.Start
84          })
85          StatusBarGroup({
86            index: 1,
87            mLayoutWeight: 0,
88            mAlignItems: HorizontalAlign.Center
89          })
90          StatusBarGroup({
91            index: 2,
92            mLayoutWeight: 1,
93            mAlignItems: HorizontalAlign.End
94          })
95        }
96        .padding({ left: $r('app.float.status_bar_padding_start'), right: $r('app.float.status_bar_padding_end') })
97        .width('100%')
98        .height('100%')
99      } else {
100        Column() {
101          StatusBarGroup({
102            index: 0,
103            mLayoutWeight: 1,
104            mAlignItems: VerticalAlign.Center
105          })
106          StatusBarGroup({
107            index: 1,
108            mLayoutWeight: 0,
109            mAlignItems: VerticalAlign.Center
110          })
111          StatusBarGroup({
112            index: 2,
113            mLayoutWeight: 1,
114            mAlignItems: VerticalAlign.Center
115          })
116        }
117        .width('100%')
118        .height('100%')
119      }
120    }.onClick(() => {
121      try {
122        commonEventManager.publish('usual.event.CLICK_STATUSBAR', (err: BusinessError) => {
123          if (err) {
124            Log.showError(TAG, `Failed to publish click event. Code is ${err.code}, message is ${err.message}`);
125          } else {
126            Log.showInfo(TAG, `Succeeded in publishing click event.`);
127          }
128        })
129      } catch (error) {
130        let err: BusinessError = error as BusinessError;
131        Log.showError(TAG, `Failed to publish click event. Code is ${err.code}, message is ${err.message}`);
132      }
133    })
134    .width('100%')
135    .height('100%')
136  }
137}
138
139@Component
140struct StatusBarBackground {
141  @State mStatusBarData: StatusBarData = ViewModel.getStatusBarData()
142  @State mBackgroundDatas: StatusBarBackgroundData[] = ViewModel.getBackgroundDatas()
143
144  aboutToAppear() {
145    Log.showInfo(TAG_StatusBarBackground, `aboutToAppear`);
146  }
147
148  aboutToDisappear() {
149    Log.showInfo(TAG_StatusBarBackground, `aboutToDisAppear`);
150  }
151
152  build() {
153    if (this.mStatusBarData.showHorizontal) {
154      Row() {
155        ForEach(this.mBackgroundDatas, (data: StatusBarBackgroundData) => {
156          if (data.width > 0) {
157            Column() {
158            }
159            .width(data.width + 'px')
160            .height('100%')
161            .backgroundColor(data.backgroundColor)
162          }
163        })
164      }
165      .width('100%')
166      .height('100%')
167    } else {
168      Column() {
169        ForEach(this.mBackgroundDatas, (data: StatusBarBackgroundData) => {
170          if (data.width > 0) {
171            Column() {
172            }
173            .width('100%')
174            .height(data.width + 'px')
175            .backgroundColor(data.backgroundColor)
176          }
177        })
178      }
179      .width('100%')
180      .height('100%')
181    }
182  }
183}
184
185@Component
186struct StatusBarGroup {
187  @StorageLink('StatusBarLayout') mStatusBarLayout: string[][] = [[], [], []]
188  private mLayoutWeight: number = 1
189  private mAlignItems: number = HorizontalAlign.Center;
190  private index: number = -1;
191  @State mStatusBarData: StatusBarData = ViewModel.getStatusBarData()
192
193  aboutToAppear() {
194    Log.showInfo(TAG_StatusBarGroup, `aboutToAppear, mLayoutWeight: ${this.mLayoutWeight} mAlignItems: ${this.mAlignItems} `);
195  }
196
197  aboutToDisappear() {
198    Log.showInfo(TAG_StatusBarGroup, `aboutToDisAppear`);
199  }
200
201  build() {
202    if (this.mStatusBarData.showHorizontal) {
203      Column() {
204        Row() {
205          ForEach(this.mStatusBarLayout[this.index], (componentName: string) => {
206            StatusBarItemLoadComponent({
207              mComponentName: componentName
208            })
209          }, (componentName: string) => componentName)
210        }.height('100%')
211      }
212      .alignItems(this.mAlignItems)
213      .layoutWeight(this.mLayoutWeight)
214      .height('100%')
215    } else {
216      Row() {
217        Column() {
218          ForEach(this.mStatusBarLayout[this.index], (componentName: string) => {
219            VerticalStatusBarItemLoadComponent({
220              mComponentName: componentName
221            })
222          }, (componentName: string) => componentName)
223        }.width('100%')
224        .alignItems(HorizontalAlign.Start)
225      }
226      .alignItems(this.mAlignItems)
227      .width('100%')
228      .layoutWeight(this.mLayoutWeight)
229    }
230  }
231}
232
233@Component
234struct VerticalStatusBarItemLoadComponent {
235  private mComponentName: string = ''
236  @State mComponentHeight: number = 0
237  @State style: VerticalStatusBarItemLoadComponentStyle = StyleConfiguration.getVerticalStatusBarItemLoadComponentStyle()
238
239  aboutToAppear() {
240    Log.showInfo(TAG_VerticalStatusBarItemLoadComponent, `aboutToAppear, mComponentName: ${this.mComponentName}`);
241  }
242
243  aboutToDisappear() {
244    Log.showInfo(TAG_VerticalStatusBarItemLoadComponent, `aboutToDisAppear, mComponentName: ${this.mComponentName}`);
245  }
246
247  build() {
248    Row() {
249      StatusBarItemLoadComponent({
250        mComponentName: this.mComponentName
251      })
252    }
253    .height(this.mComponentHeight + 'px')
254    .onAreaChange((e, e2) => {
255      Log.showInfo(TAG_VerticalStatusBarItemLoadComponent, `onAreaChange, mComponentName: ${this.mComponentName} e: ${JSON.stringify(e)} e2: ${JSON.stringify(e2)}`);
256      this.mComponentHeight = e2.width > 0 ? this.style.statusBarVerticalComponentHeight : 0
257      Log.showInfo(TAG_VerticalStatusBarItemLoadComponent, `onAreaChange, mComponentName: ${this.mComponentName} mComponentHeight: ${this.mComponentHeight}`);
258    })
259  }
260}
261
262@Component
263struct StatusBarItemLoadComponent {
264  private mComponentName: string = ''
265  aboutToAppear() {
266    Log.showInfo(TAG_StatusBarItemLoadComponent, `aboutToAppear, mComponentName: ${this.mComponentName} `)
267  }
268
269  aboutToDisappear() {
270    Log.showInfo(TAG_StatusBarGroup, `aboutToDisAppear, mComponentName: ${this.mComponentName} `)
271  }
272
273  build() {
274    Row() {
275      if (this.mComponentName == FASlotName.EMPTY) {
276        StatusBarEmptyIcon()
277      } else if (this.mComponentName == FASlotName.WIFI) {
278        WifiIcon()
279      } else if (this.mComponentName == FASlotName.BLUETOOTH) {
280        BluetoothIcon()
281      } else if (this.mComponentName == FASlotName.SIGNAL) {
282        SignalIcon()
283      } else if (this.mComponentName == FASlotName.CLOCK) {
284        ClockIcon()
285      } else if (this.mComponentName == FASlotName.BATTERY) {
286        BatteryIcon()
287      } else if (this.mComponentName == FASlotName.AIR_PLANE) {
288        AirplaneIcon()
289      } else if (this.mComponentName == FASlotName.CAPSULE) {
290        CapsuleIcon()
291      } else if (this.mComponentName == FASlotName.NOTIFICATION) {
292        StatusBarNotificationIcon()
293      } else if (this.mComponentName == FASlotName.LOCATION) {
294        LocationIcon()
295      } else if (this.mComponentName == FASlotName.RING_MODE) {
296        RingModeIcon()
297      } else if (this.mComponentName == FASlotName.NFC) {
298        if (isNfcAvailable()) {
299          NfcIcon()
300        }
301      } else {
302        IconItemComponent({
303          keyId: this.mComponentName
304        })
305      }
306    }.height('100%')
307    .onAreaChange((e: Area, e2: Area) => {
308      Log.showInfo(TAG_StatusBarItemLoadComponent, `onAreaChange, componentName: ${this.mComponentName}}, new area: ${JSON.stringify(e2)} `)
309      ViewModel.updateComponentArea(this.mComponentName, e2)
310    })
311  }
312}
313
314@Component
315struct StatusBarEmptyIcon {
316  @StorageLink('StatusBarEmptyWidth') mStatusBarEmptyWidth: number = 0
317  @State mTintContentInfo: TintContentInfo = ViewModel.getEmptyTintContentInfo()
318
319  aboutToAppear() {
320    Log.showInfo(TAG_StatusBarEmptyIcon, `aboutToAppear, mStatusBarEmptyWidth: ${this.mStatusBarEmptyWidth} `)
321  }
322
323  aboutToDisappear() {
324    Log.showInfo(TAG_StatusBarEmptyIcon, `aboutToDisAppear`);
325  }
326
327  build() {
328    Row().width(this.mStatusBarEmptyWidth).height('100%')
329  }
330}
331
332@Component
333struct StatusBarNotificationIcon {
334  @StorageLink('notificationList') notificationList: NotificationItemData[][] = []
335  @StorageLink('StatusCoefficient') StatusCoefficient: number = 1.0
336  @State mTintContentInfo: TintContentInfo = ViewModel.getNotificationTintContentInfo()
337  @State styleCommon: CommonStyle = StyleConfigurationCommon.getCommonStyle()
338  @State style: StatusBarNotificationIconStyle = StyleConfiguration.getStatusBarNotificationIconStyle()
339
340  aboutToAppear() {
341    Log.showInfo(TAG_StatusBarNotificationIcon, `aboutToAppear`);
342  }
343
344  aboutToDisappear() {
345    Log.showInfo(TAG_StatusBarNotificationIcon, `aboutToDisAppear`);
346  }
347
348  build() {
349    Row() {
350      if (this.notificationList.length > 0) {
351        Row().height(1).width(this.styleCommon.statusBarMarginLeftRight)
352      }
353      if (this.notificationList.length > 3) {
354        ForEach(this.notificationList.slice(0, 3), (item: NotificationItemData[]) => {
355          Image(item[0].smallIcon)
356            .objectFit(ImageFit.ScaleDown)
357            .height(this.style.iconHeight)
358            .width(this.style.iconWidth)
359            .margin({ right: this.style.iconSpace })
360            .fillColor(this.mTintContentInfo.contentColor)
361        })
362        Row() {
363          Text('...')
364            .fontSize(this.styleCommon.statusBarFontSize)
365            .fontColor(this.mTintContentInfo.contentColor)
366        }
367      } else {
368        ForEach(this.notificationList.map((item, index1) => {
369          let res: Item = { index: index1, data: item }
370          return res
371        }), (res: Item) => {
372          if (res.index > 0) {
373            Row().height(1).width(this.style.iconSpace)
374          }
375          Image(res.data[0].smallIcon)
376            .objectFit(ImageFit.ScaleDown)
377            .height(this.style.iconHeight)
378            .width(this.style.iconWidth)
379            .fillColor(this.mTintContentInfo.contentColor)
380        })
381      }
382      if (this.notificationList.length > 0) {
383        Row().height(1).width(this.styleCommon.statusBarMarginLeftRight)
384      }
385    }
386    .height('100%')
387  }
388}
389