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 '@ohos/common';
17import { Trace } from '@ohos/common';
18import { windowManager } from '@ohos/common';
19import { SettingItemInfo } from '@ohos/common';
20import SettingsStage from '../common/SettingsStage';
21import SettingsStyleConstants from '../common/constants/SettingsStyleConstants';
22import SettingsPresenter from '../common/presenter/SettingsPresenter';
23import SettingItemOption from '@ohos/common/src/main/ets/default/bean/SettingItemOption';
24
25let mSettingsPresenter: SettingsPresenter;
26const TAG = 'Settings';
27
28@Entry
29@Component
30struct Index {
31  private mSettingsStage: SettingsStage = new SettingsStage();
32  private mDevice = SettingsStyleConstants.DEFAULT_DEVICE_TYPE_PHONE;
33  @State mSettingsPresenter: SettingsPresenter | null = null;
34
35  onPageShow(): void { }
36
37  aboutToAppear(): void {
38    this.getDeviceType();
39    this.mSettingsStage.onCreate();
40    this.mSettingsPresenter = SettingsPresenter.getInstance();
41  }
42
43  aboutToDisappear(): void {
44    this.mSettingsStage.onDestroy();
45  }
46
47  async getDeviceType() {
48    try {
49      let sysWidth = px2vp(windowManager.getWindowWidth());
50      let sysHeight = px2vp(windowManager.getWindowHeight());
51      if (sysWidth > sysHeight) {
52        this.mDevice = SettingsStyleConstants.DEFAULT_DEVICE_TYPE_PAD;
53      }
54    } catch (e) {
55      Log.showError(TAG, `getWindowWidth or getWindowHeight error: ${JSON.stringify(e)}`);
56    }
57  }
58
59  build() {
60    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
61      Column() {
62        Column() {
63          top_bar()
64        }
65        .alignItems(HorizontalAlign.Start)
66        .width(SettingsStyleConstants.PERCENTAGE_100)
67        .height(SettingsStyleConstants.DEFAULT_VP_56)
68
69        Column() {
70          Text($r('app.string.layout'))
71            .fontSize($r('app.float.layout_title_font_size'))
72            .fontColor(SettingsStyleConstants.DEFAULT_LAYOUT_FONT_COLOR)
73            .width(SettingsStyleConstants.PERCENTAGE_100)
74            .height(SettingsStyleConstants.PERCENTAGE_100)
75            .align(Alignment.BottomStart)
76        }
77        .padding({ left: 24, bottom: 10 })
78        .width(SettingsStyleConstants.PERCENTAGE_100)
79        .height(SettingsStyleConstants.DEFAULT_VP_48)
80
81        Column() {
82          SettingPage()
83        }
84        .alignItems(HorizontalAlign.Center)
85        .width(SettingsStyleConstants.PERCENTAGE_100)
86      }
87      .width(this.mDevice === SettingsStyleConstants.DEFAULT_DEVICE_TYPE_PHONE ?
88      SettingsStyleConstants.PERCENTAGE_100 : 976)
89      .height(SettingsStyleConstants.PERCENTAGE_100)
90
91      if (this.traceBuildEnd()) { }
92    }
93    .backgroundColor(SettingsStyleConstants.DEFAULT_BACKGROUND_COLOR)
94    .width(SettingsStyleConstants.PERCENTAGE_100)
95    .height(SettingsStyleConstants.PERCENTAGE_100)
96  }
97
98  private traceBuildEnd(): boolean {
99    Trace.end(Trace.CORE_METHOD_START_SETTINGS)
100    return true;
101  }
102}
103
104@Component
105struct top_bar {
106  build() {
107    Row({ space: 16 }) {
108      Image($r('app.media.ic_back'))
109        .margin({ left: 24 })
110        .objectFit(ImageFit.Contain)
111        .width(SettingsStyleConstants.DEFAULT_VP_24)
112        .height(SettingsStyleConstants.DEFAULT_VP_24)
113        .onClick(() => {
114          SettingsPresenter.getInstance().backToTheDesktop();
115        })
116
117      Text($r('app.string.into_settings'))
118        .fontSize(SettingsStyleConstants.DEFAULT_VP_20)
119        .fontWeight(FontWeight.Medium)
120        .height(SettingsStyleConstants.DEFAULT_VP_28)
121        .width(SettingsStyleConstants.DEFAULT_VP_296)
122    }
123    .width(SettingsStyleConstants.PERCENTAGE_100)
124    .height(SettingsStyleConstants.PERCENTAGE_100)
125  }
126}
127
128@Component
129struct SettingPage {
130  @State settingList: SettingItemInfo[] = [];
131
132  aboutToAppear(): void {
133    this.settingList = SettingsPresenter.getInstance().getSettingList();
134    Log.showInfo(TAG, `aboutToAppear SettingList length: ${this.settingList.length}`);
135  }
136
137  build() {
138    Column() {
139      ForEach(this.settingList, (item: SettingItemInfo) => {
140        SettingItem({
141          ida: item.ida,
142          settingName: item.settingName,
143          settingValue: item.settingValue,
144          valueList: item.valueList,
145          settingType: item.settingType
146        })
147      }, (item: SettingItemInfo) => JSON.stringify(item))
148    }
149    .width(SettingsStyleConstants.PERCENTAGE_100)
150    .height(SettingsStyleConstants.DEFAULT_VP_56)
151    .align(Alignment.Center)
152    .padding({ left: 12, right: 12 })
153  }
154}
155
156@Component
157struct SettingItem {
158  @State ida: number = 0;
159  @State settingValue: string = ' ';
160  @State settingName: string = ' ';
161  @StorageLink('NavigationBarStatusValue') navigationBarStatusValue: boolean = false;
162  private settingType?: number;
163  private valueList: SettingItemOption[] = [];
164  dialogController: CustomDialogController | null = new CustomDialogController({
165    builder: SettingsDialog(),
166    cancel: this.cancelDialog,
167    autoCancel: true
168  });
169  callback = (data: string) => {
170    this.settingValue = data;
171  }
172
173  cancelDialog() {
174    Log.showDebug(TAG, 'cancelDialog');
175  }
176
177  aboutToAppear(): void {
178    SettingsPresenter.getInstance().initNavigationBarStatusValue();
179    if (this.settingType == 1) {
180      SettingsPresenter.getInstance().registerValueCallback(this.ida, this.callback);
181    }
182  }
183
184  aboutToDisappear(): void {
185    this.dialogController = null;
186  }
187
188  build() {
189    Flex({
190      direction: FlexDirection.Row,
191      alignItems: ItemAlign.Center,
192      justifyContent: FlexAlign.SpaceBetween
193    }) {
194      Column() {
195        Text(this.settingName)
196          .lineHeight(SettingsStyleConstants.DEFAULT_VP_22)
197          .height(SettingsStyleConstants.DEFAULT_VP_22)
198          .width(SettingsStyleConstants.DEFAULT_VP_230)
199          .fontSize(SettingsStyleConstants.DEFAULT_VP_16)
200          .align(Alignment.Start)
201      }
202
203      if (this.settingType == 1) {
204        Column() {
205          Row() {
206            Text(this.settingValue)
207              .lineHeight(SettingsStyleConstants.DEFAULT_VP_48)
208              .height(SettingsStyleConstants.DEFAULT_VP_48)
209              .width(SettingsStyleConstants.DEFAULT_VP_60)
210              .fontSize(SettingsStyleConstants.DEFAULT_VP_16)
211              .align(Alignment.End)
212            Image($r('app.media.ic_settings_arrow'))
213              .margin({ top: SettingsStyleConstants.DEFAULT_VP_16 })
214              .height(SettingsStyleConstants.DEFAULT_VP_16)
215              .width(SettingsStyleConstants.DEFAULT_VP_20)
216              .align(Alignment.End)
217          }
218        }
219        .onClick(() => {
220          AppStorage.setOrCreate('ida', this.ida);
221          AppStorage.setOrCreate('valueList', this.valueList);
222          AppStorage.setOrCreate('settingValue', this.settingValue);
223          if (this.dialogController) {
224            this.dialogController.open();
225          }
226        })
227      } else {
228        Toggle({ type: ToggleType.Switch, isOn: this.navigationBarStatusValue })
229          .width(50)
230          .height(40)
231          .onChange((isOn: boolean) => {
232            Log.showDebug(TAG, `SettingItemToggle onChange for GestureNavigation Enable: ${isOn}`);
233            SettingsPresenter.getInstance().sendLocalEvent(isOn ? '0' : '1');
234          })
235      }
236    }
237    .width(SettingsStyleConstants.PERCENTAGE_100)
238    .height(SettingsStyleConstants.PERCENTAGE_100)
239    .padding({ left: 12, right: 12 })
240    .borderRadius(SettingsStyleConstants.DEFAULT_VP_16)
241    .backgroundColor(SettingsStyleConstants.DEFAULT_SETTING_PAGE_COLOR)
242  }
243}
244
245@CustomDialog
246@Component
247struct SettingsDialog {
248  controller?: CustomDialogController;
249  action: () => void = () => {
250  };
251  cancel: () => void = () => {
252  };
253  @StorageLink('valueList') valueList: SettingItemOption[] = [];
254  @StorageLink('ida') ida: number = 0;
255  @StorageLink('settingValue') settingValue: String = '';
256
257  aboutToDisappear(): void {
258  }
259
260  build() {
261    Column() {
262      ForEach(this.valueList, (item: SettingItemOption) => {
263        Row() {
264          Text(item.name)
265            .margin({ left: SettingsStyleConstants.DEFAULT_VP_10 })
266            .align(Alignment.Start)
267            .width(SettingsStyleConstants.PERCENTAGE_85)
268            .fontSize(SettingsStyleConstants.DEFAULT_VP_30)
269            .fontColor(SettingsStyleConstants.DEFAULT_DIALOG_FONT_COLOR)
270          Radio({ value: item.value, group: ('' + this.ida) })
271            .enabled(false)
272            .checked(item.name === this.settingValue)
273            .width(SettingsStyleConstants.DEFAULT_VP_30)
274            .height(SettingsStyleConstants.DEFAULT_VP_30)
275            .onChange((isChecked: boolean) => {})
276        }.width(SettingsStyleConstants.PERCENTAGE_100)
277        .height(SettingsStyleConstants.DEFAULT_VP_80)
278        .onClick(() => {
279          SettingsPresenter.getInstance().changeSettingValue(this.ida, item.name);
280          SettingsPresenter.getInstance().setSettingsValue(this.ida, item.value);
281          if (this.controller) {
282            this.controller.close();
283          }
284          this.action();
285        })
286      }, (item: SettingItemOption) => JSON.stringify(item))
287      Text($r('app.string.cancel'))
288        .textAlign(TextAlign.Center)
289        .height(SettingsStyleConstants.DEFAULT_VP_80)
290        .width(SettingsStyleConstants.PERCENTAGE_100)
291        .fontSize(SettingsStyleConstants.DEFAULT_VP_30)
292        .fontColor(Color.Blue)
293        .onClick(() => {
294          if (this.controller) {
295            this.controller.close();
296          }
297          this.action();
298        })
299    }.padding(SettingsStyleConstants.DEFAULT_VP_20)
300    .backgroundColor(SettingsStyleConstants.DEFAULT_SETTING_PAGE_COLOR)
301    .borderRadius(SettingsStyleConstants.DEFAULT_VP_30)
302  }
303}
304