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