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 Audio from '@ohos.multimedia.audio';
17import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
18import { SubHeader } from '../../../../../../common/component/src/main/ets/default/textComponent';
19import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
20import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
21import { registerObserver, RingerModel, VolumeModel } from '../model/volumeControlImpl/VolumeControlModel';
22
23const VOLUME_MIN_VALUE = 0;
24const VOLUME_MAX_VALUE = 15;
25
26/**
27 * Volume control
28 */
29@Entry
30@Component
31export struct VolumeControl {
32  private TAG = ConfigData.TAG + ' VolumeControl ';
33
34  build() {
35    Column() {
36      GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) {
37        Column() {
38          //head
39          HeadComponent({ headName: $r('app.string.volumeControlTab') });
40
41          SubHeader({ titleContent: $r('app.string.soundMode') });
42
43          // sound mode
44          AudioRingerModeComponent();
45
46          SubHeader({ titleContent: $r('app.string.volumeControl') });
47
48          // volume control
49          VolumeControlComponent();
50        }
51        .useSizeType({
52          sm: { span: 4, offset: 0 },
53          md: { span: 6, offset: 1 },
54          lg: { span: 8, offset: 2 }
55        })
56      }
57      .width(ConfigData.WH_100_100)
58      .height(ConfigData.WH_100_100)
59    }
60    .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
61    .width(ConfigData.WH_100_100)
62    .height(ConfigData.WH_100_100)
63  }
64
65  aboutToAppear() {
66    LogUtil.info(`${this.TAG} aboutToAppear in`);
67    registerObserver();
68    LogUtil.info(`${this.TAG} aboutToAppear out`);
69  }
70}
71
72/**
73 * AudioRingerMode component
74 */
75@Component
76struct AudioRingerModeComponent {
77  @StorageLink('ringerModeNormal') ringerModeNormal: boolean = false;
78  @StorageLink('ringerModeSilent') ringerModeSilent: boolean = false;
79  private ringerSilentModel: RingerModel = new RingerModel(Audio.AudioRingMode.RINGER_MODE_SILENT);
80  private ringerNormalModel: RingerModel = new RingerModel(Audio.AudioRingMode.RINGER_MODE_NORMAL);
81  private TAG = ConfigData.TAG + ' AudioRingerModeComponent ';
82
83  build() {
84    Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround }) {
85      Row() {
86        Blank()
87
88        AudioRingerModeItem({
89          checked: $ringerModeNormal,
90          audioRingerModel: this.ringerNormalModel,
91          image: $r("app.media.ic_ring"),
92          text: $r('app.string.soundModeSound')
93        });
94
95        Blank()
96
97        Divider()
98          .vertical(true)
99          .margin({ bottom: 14 })
100          .color($r('sys.color.ohos_id_color_list_separator'))
101
102        Blank()
103
104        AudioRingerModeItem({
105          checked: $ringerModeSilent,
106          audioRingerModel: this.ringerSilentModel,
107          image: $r("app.media.ic_ring_off"),
108          text: $r('app.string.soundModeSilent')
109        });
110
111        Blank()
112      }
113      .width(ConfigData.WH_100_100)
114    }
115    .borderRadius($r('app.float.radius_24'))
116    .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary"))
117    .width(ConfigData.WH_100_100)
118    .height($r('app.float.wh_value_119'))
119    .padding({
120      top: $r('app.float.distance_14'),
121      bottom: $r('app.float.distance_2')
122    })
123  }
124
125  aboutToAppear() {
126    LogUtil.info(`${this.TAG} aboutToAppear in`);
127    LogUtil.info(`${this.TAG} aboutToAppear out`);
128  }
129}
130
131/**
132 * AudioRingerMode item
133 */
134@Component
135struct AudioRingerModeItem {
136  @Link checked: boolean;
137  private audioRingerModel: RingerModel | null = null;
138  private image: Resource | null = null;
139  private text: string | Resource = '';
140
141  build() {
142    Column() {
143      Image(this.image)
144        .width($r('app.float.wh_value_24'))
145        .height($r('app.float.wh_value_24'))
146        .objectFit(ImageFit.Contain)
147        .fillColor($r("sys.color.ohos_fa_icon_secondary"))
148
149      Text(this.text)
150        .fontColor($r("app.color.font_color_182431"))
151        .fontSize($r("sys.float.ohos_id_text_size_body2"))
152        .lineHeight($r("app.float.lineHeight_19"))
153        .fontWeight(FontWeight.Regular)
154        .textAlign(TextAlign.Center)
155        .margin({ top: $r('app.float.distance_8') });
156
157      Radio({ value: '', group: '' })
158        .width($r('app.float.wh_value_24'))
159        .height($r('app.float.wh_value_24'))
160        .margin({ top: $r('app.float.distance_4') })
161        .checked(this.checked)
162        .onChange((vue) => {
163          if (vue) {
164            this.audioRingerModel?.setRingerMode();
165          }
166        })
167    }
168    .alignItems(HorizontalAlign.Center)
169    .onClick(() => {
170      LogUtil.info(ConfigData.TAG + 'AudioRingerModeItem : item is clicked');
171      this.audioRingerModel?.setRingerMode();
172    });
173  }
174}
175
176/**
177 * Volume control component
178 */
179@Component
180struct VolumeControlComponent {
181  @StorageLink('volume_ringtone') volumeRingTone: number = 2;
182  @StorageLink('volume_media') volumeMedia: number = 2;
183  @StorageLink('volume_voicecall') volumeVoiceCall: number = 2;
184  private voiceCallModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.VOICE_CALL);
185  private ringtoneModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.RINGTONE);
186  private mediaModel: VolumeModel = new VolumeModel(Audio.AudioVolumeType.MEDIA);
187  private TAG = ConfigData.TAG + ' VolumeControlComponent ';
188
189  build() {
190    Column() {
191      VolumeControlItem({
192        image: this.volumeRingTone === 0 ? $r("app.media.ic_ring_off") : $r("app.media.ic_ring"),
193        volumeValue: $volumeRingTone,
194        volumeModel: this.ringtoneModel,
195        text: $r("app.string.volumeControlRing") })
196
197      VolumeControlItem({
198        image: this.volumeMedia === 0 ? $r("app.media.ic_media_off") : $r("app.media.ic_media"),
199        volumeValue: $volumeMedia,
200        volumeModel: this.mediaModel,
201        text: $r("app.string.volumeControlMedia") })
202
203      VolumeControlItem({
204        image: $r("app.media.ic_call"),
205        volumeValue: $volumeVoiceCall,
206        volumeModel: this.voiceCallModel,
207        text: $r("app.string.volumeControlCall") })
208    }
209    .width(ConfigData.WH_100_100)
210    .borderRadius($r('app.float.radius_24'))
211    .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary"))
212    .padding($r('app.float.distance_12'))
213  }
214
215  aboutToAppear(): void {
216    LogUtil.info(`${this.TAG} aboutToAppear in`);
217    LogUtil.info(`${this.TAG} aboutToAppear out`);
218  }
219}
220
221/**
222 * Volume control item
223 */
224@Component
225struct VolumeControlItem {
226  @Link volumeValue: number;
227  private volumeModel: VolumeModel | null = null;
228  private image: Resource | null = null;
229  private text: string | Resource = '';
230
231  build() {
232    Column() {
233      Row() {
234        Image(this.image)
235          .width($r('app.float.wh_value_20'))
236          .height($r('app.float.wh_value_20'))
237          .fillColor($r("sys.color.ohos_fa_icon_secondary"))
238          .objectFit(ImageFit.Contain)
239
240        Text(this.text)
241          .fontSize($r("app.float.font_16"))
242          .lineHeight($r("app.float.lineHeight_22"))
243          .fontColor($r('sys.color.ohos_id_color_text_secondary'))
244          .textAlign(TextAlign.Start)
245          .margin({ left: $r('app.float.distance_12') })
246          .width(ConfigData.WH_100_100);
247      }
248      .margin({ bottom: $r('app.float.distance_1') })
249      .width(ConfigData.WH_100_100)
250      .align(Alignment.Center);
251
252      Slider({
253        value: this.volumeValue,
254        min: VOLUME_MIN_VALUE,
255        max: VOLUME_MAX_VALUE,
256        style: SliderStyle.InSet
257      })
258        .selectedColor($r('app.color.font_color_007DFF'))
259        .blockColor(Color.White)
260        .height($r('app.float.wh_value_40'))
261        .width(ConfigData.WH_100_100)
262        .onChange((value: number) => {
263          this.volumeModel?.setVolume(value);
264        });
265    }
266    .margin({ top: $r("app.float.distance_12") })
267    .width(ConfigData.WH_100_100);
268  }
269}