1/**
2 * Copyright (c) 2023-2023 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.   clickResponseTime   ignoreRepeatClick
14 */
15
16import config from '@ohos.accessibility.config';
17import { BusinessError } from '@ohos.base';
18import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil';
19import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData';
20import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent';
21import { AccessibilitySettingModel } from '../model/accessibilityImpl/AccessibilitySettingModel';
22
23const TAG = ConfigData.TAG + 'AccessibilityScreenTouch: ';
24const BASIC_SUSTAIN_DURATION_SHORT = 'Short';
25const BASIC_SUSTAIN_DURATION_CENTRE = 'Medium';
26const BASIC_SUSTAIN_DURATION_LONG = 'Long';
27
28@Entry
29@Component
30struct AccessibilityScreenTouch {
31  @State clickResponseTimeText: string = '';
32  @State checked: config.ClickResponseTime = 'Short';
33  @State ignoreRepeatClickIsOn: boolean = false;
34  @State ignoreRepeatClickTimeText: string = '';
35  @State setIgnoreRepeatClickTime: number = 0;
36  @State ignoreRepeatFlag: boolean = false;
37  @State allClickResponseTimeList: config.ClickResponseTime[] = [BASIC_SUSTAIN_DURATION_SHORT, BASIC_SUSTAIN_DURATION_CENTRE, BASIC_SUSTAIN_DURATION_LONG];
38  private SelectAbilityScalingDialog: CustomDialogController = new CustomDialogController({
39    builder: SelectAbilityScalingInformation({
40      allClickResponseTimeList: $allClickResponseTimeList,
41      clickResponseTimeText: $clickResponseTimeText,
42      checked: $checked,
43    }),
44    alignment: DialogAlignment.Bottom,
45    offset: ({ dx: 0, dy: '-12dp' }),
46    autoCancel: true,
47    customStyle: true,
48  });
49
50  build() {
51    Column() {
52      GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) {
53        Column() {
54          HeadComponent({ headName: $r('app.string.screen_touch'), isActive: true });
55
56          Column() {
57            Row() {
58              Column() {
59                Text($r('app.string.click_duration'))
60                  .fontColor($r('sys.color.ohos_fa_text_primary'))
61                  .fontFamily('HarmonyHeiTi')
62                  .fontWeight(FontWeight.Medium)
63                  .fontSize($r("sys.float.ohos_id_text_size_body1"));
64              }
65              .alignItems(HorizontalAlign.Start);
66
67              Blank();
68
69              Row() {
70                Text(this.clickResponseTimeText)
71                  .margin({ right: $r('app.float.distance_4') })
72                  .fontSize($r('sys.float.ohos_id_text_size_body2'))
73                  .fontColor($r('sys.color.ohos_fa_text_secondary'));
74
75                Image('/res/image/ic_settings_arrow.svg')
76                  .width($r('app.float.wh_value_12'))
77                  .height($r('app.float.wh_value_24'))
78                  .fillColor($r('sys.color.ohos_id_color_primary'))
79                  .opacity($r('app.float.opacity_0_2'));
80              }
81            }
82            .padding({ left: $r('app.float.wh_value_12'), right: $r('app.float.distance_6') })
83            .alignItems(VerticalAlign.Center)
84            .width(ConfigData.WH_100_100)
85            .height($r('app.float.wh_value_56'))
86            .onClick(() => {
87              this.SelectAbilityScalingDialog.open();
88            });
89          }
90          .height($r('app.float.wh_value_56'))
91          .width(ConfigData.WH_100_100)
92          .margin({ top: $r('app.float.distance_20') })
93          .borderRadius($r('app.float.radius_24'))
94          .backgroundColor($r('sys.color.ohos_id_color_foreground_contrary'));
95
96          Column() {
97            Row() {
98              Text($r('app.string.Ignore_duplicate_clicks'))
99                .fontSize($r('sys.float.ohos_id_text_size_body1'))
100                .fontColor($r('sys.color.ohos_id_color_text_primary'))
101                .fontWeight(FontWeight.Medium)
102                .textAlign(TextAlign.Start);
103              Blank();
104              Toggle({ type: ToggleType.Switch, isOn: this.ignoreRepeatClickIsOn })
105                .width('36vp')
106                .height('20vp')
107                .selectedColor('#007DFF')
108                .onChange((isOn: boolean) => {
109                  this.setIgnoreRepeatClickState(isOn);
110                });
111            }
112            .height($r('app.float.wh_value_56'))
113            .width(ConfigData.WH_100_100)
114            .alignItems(VerticalAlign.Center)
115            .padding({ left: $r('app.float.wh_value_12'), right: $r('app.float.wh_value_6') })
116            .backgroundColor($r('app.color.white_bg_color'))
117            .borderRadius($r('app.float.radius_24'));
118          }
119          .height($r('app.float.wh_value_56'))
120          .width(ConfigData.WH_100_100)
121          .margin({ top: $r('app.float.distance_20') })
122          .borderRadius($r('app.float.radius_24'))
123          .backgroundColor($r('sys.color.ohos_id_color_foreground_contrary'));
124
125          Text($r('app.string.Ignore_duplicate_clicks_illustrate'))
126            .width(ConfigData.WH_100_100)
127            .fontSize($r('app.float.font_14'))
128            .fontColor($r('sys.color.ohos_id_color_text_secondary'))
129            .height($r('app.float.wh_value_52'))
130            .lineHeight($r('app.float.wh_value_20'))
131            .padding({
132              left: $r('app.float.wh_value_12'),
133              top: $r('app.float.distance_4'),
134              bottom: $r('app.float.distance_24'),
135            });
136
137          Column() {
138            Text($r('app.string.time_interval'))
139              .width(ConfigData.WH_100_100)
140              .fontSize($r('app.float.font_14'))
141              .fontColor($r('sys.color.ohos_id_color_text_secondary'))
142              .height($r('app.float.wh_value_52'))
143              .lineHeight($r('app.float.wh_value_20'))
144              .padding({
145                left: $r('app.float.wh_value_12'),
146                top: $r('app.float.distance_4'),
147              });
148
149            Row() {
150              Column() {
151                Row() {
152                  Text(this.ignoreRepeatClickTimeText)
153                    .fontSize($r('sys.float.ohos_id_text_size_body1'))
154                    .fontColor($r('sys.color.ohos_id_color_text_primary'))
155                    .fontWeight(FontWeight.Medium)
156                    .textAlign(TextAlign.Center);
157                }
158                .height($r('app.float.wh_value_19'))
159                .width(ConfigData.WH_100_100)
160                .alignItems(VerticalAlign.Center)
161                .justifyContent(FlexAlign.Center)
162                .margin({top:$r('app.float.wh_value_16')})
163                .backgroundColor($r('app.color.white_bg_color'))
164                .borderRadius($r('app.float.radius_24'));
165
166                Row() {
167                  Image('/res/image/ic_public_remove.svg')
168                    .height($r('app.float.wh_value_24'))
169                    .width($r('app.float.wh_value_24'))
170                    .fillColor($r('sys.color.ohos_id_color_primary'))
171                    .margin({bottom:$r('app.float.wh_value_18')})
172                    .onClick(() => {
173                      this.onIgnoreRepeatClickTimeChange('minus')
174                    });
175
176                  Slider({
177                    value: this.setIgnoreRepeatClickTime,
178                    min: 0,
179                    max: 100,
180                    step: 25,
181                    style: SliderStyle.InSet,
182                  })
183                    .selectedColor($r('app.color.font_color_007DFF'))
184                    .blockColor(Color.Blue)
185                    .showSteps(true)
186                    .height($r('app.float.wh_value_20'))
187                    .width(ConfigData.WH_83_100)
188                    .margin({top:$r('app.float.wh_value_10'),bottom:$r('app.float.wh_value_22'),left:$r('app.float.wh_value_12'),right:$r('app.float.wh_value_12')})
189                    .borderRadius($r('app.float.radius_24'))
190                    .onChange((value: number, mode: SliderChangeMode) => {
191                      this.setIgnoreRepeatClickTimeValue(value, mode);
192                    });
193
194                  Image('/res/image/ic_public_add_norm.svg')
195                    .height($r('app.float.wh_value_24'))
196                    .width($r('app.float.wh_value_24'))
197                    .fillColor($r('sys.color.ohos_id_color_primary'))
198                    .margin({bottom:$r('app.float.wh_value_18')})
199                    .onClick(() => {
200                      this.onIgnoreRepeatClickTimeChange('add')
201                    });
202                }
203                .width(ConfigData.WH_100_100)
204                .height($r('app.float.wh_value_52'))
205                .justifyContent(FlexAlign.SpaceBetween)
206                .padding({ left: $r('app.float.wh_value_6'), right: $r('app.float.wh_value_6') })
207                .backgroundColor($r("app.color.white_bg_color"))
208                .borderRadius($r('app.float.radius_24'));
209              }
210              .width(ConfigData.WH_100_100);
211            }
212            .width(ConfigData.WH_100_100)
213            .alignItems(VerticalAlign.Center)
214            .padding({ left: $r('app.float.wh_value_6'), right: $r('app.float.wh_value_6') })
215            .backgroundColor($r("app.color.white_bg_color"))
216            .borderRadius($r('app.float.radius_24'));
217          }
218          .width(ConfigData.WH_100_100)
219          .height(ConfigData.WH_100_100)
220          .visibility(this.ignoreRepeatClickIsOn ? Visibility.Visible : Visibility.Hidden)
221          .margin({ top: $r('app.float.wh_value_30') });
222        }
223        .useSizeType({
224          sm: { span: 4, offset: 0 },
225          md: { span: 6, offset: 1 },
226          lg: { span: 8, offset: 2 },
227        });
228      }
229      .width(ConfigData.WH_100_100)
230      .height(ConfigData.WH_100_100);
231    }
232    .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
233    .width(ConfigData.WH_100_100)
234    .height(ConfigData.WH_100_100);
235  }
236
237  setIgnoreRepeatClickState(isOn: boolean): void {
238    LogUtil.info(`${TAG} setIgnoreRepeatClickState ${isOn}`);
239    if (isOn) {
240      this.ignoreRepeatClickIsOn = true;
241      AccessibilitySettingModel.accessibilityConfigSetting('ignoreRepeatClick', true);
242    } else {
243      this.ignoreRepeatClickIsOn = false;
244      AccessibilitySettingModel.accessibilityConfigSetting('ignoreRepeatClick', false);
245    }
246  }
247
248  setIgnoreRepeatClickTimeValue(value: number, mode: SliderChangeMode): void {
249    LogUtil.info(`${TAG} setIgnoreRepeatClickTimeValue ${value}${mode}`);
250    this.setIgnoreRepeatClickTime = value;
251    if (mode == SliderChangeMode.End || mode == SliderChangeMode.Click) {
252      this.setNumberBecomeValue(value);
253    }
254  }
255
256  onIgnoreRepeatClickTimeChange(value: string): void {
257    LogUtil.info(`${TAG} onIgnoreRepeatClickTimeChange ${this.setIgnoreRepeatClickTime}`);
258    if (value === 'minus') {
259      if (this.setIgnoreRepeatClickTime > 0) {
260        this.setIgnoreRepeatClickTime = this.setIgnoreRepeatClickTime - 25;
261        this.setNumberBecomeValue(this.setIgnoreRepeatClickTime)
262      }
263      return;
264    } else {
265      if (this.setIgnoreRepeatClickTime < 100) {
266        this.setIgnoreRepeatClickTime = this.setIgnoreRepeatClickTime + 25;
267        this.setNumberBecomeValue(this.setIgnoreRepeatClickTime)
268      }
269      return;
270    }
271  }
272
273  setNumberBecomeValue(value: number): void {
274    LogUtil.info(`${TAG} setNumberBecomeValue ${value}`);
275    let repeatClickValue: config.RepeatClickInterval = 'Shortest';
276    switch (value) {
277      case 0:
278        repeatClickValue = 'Shortest';
279        this.ignoreRepeatClickTimeText = (Object)($r('app.string.shortest'));
280        break;
281      case 25:
282        repeatClickValue = 'Short';
283        this.ignoreRepeatClickTimeText = (Object)($r('app.string.short'));
284        break;
285      case 50:
286        repeatClickValue = 'Medium';
287        this.ignoreRepeatClickTimeText = (Object)($r('app.string.centre'));
288        break;
289      case 75:
290        repeatClickValue = 'Long';
291        this.ignoreRepeatClickTimeText = (Object)($r('app.string.long'));
292        break;
293      case 100:
294        repeatClickValue = 'Longest';
295        this.ignoreRepeatClickTimeText = (Object)($r('app.string.longest'));
296        break;
297      default:
298        repeatClickValue = 'Shortest';
299        this.ignoreRepeatClickTimeText = (Object)($r('app.string.shortest'));
300        LogUtil.error(`${TAG} setNumberBecomeValue fail reason: ${value}`);
301        break;
302
303    }
304    AccessibilitySettingModel.accessibilityIgnoreRepeatClickTimeSet(repeatClickValue);
305  }
306
307  async getColorCorrectionStateAndTarget(): Promise<void> {
308    await config.clickResponseTime.get().then((data) => {
309      LogUtil.info(`${TAG} get clickResponseTime success: ${data}`);
310      if (data === 'Short') {
311        this.checked = BASIC_SUSTAIN_DURATION_SHORT;
312        this.clickResponseTimeText = (Object)($r('app.string.default_short'));
313      } else if (data === 'Medium') {
314        this.checked = BASIC_SUSTAIN_DURATION_CENTRE;
315        this.clickResponseTimeText = (Object)($r('app.string.centre'));
316      } else {
317        this.checked = BASIC_SUSTAIN_DURATION_LONG;
318        this.clickResponseTimeText = (Object)($r('app.string.long'));
319      }
320    }).catch((err: BusinessError) => {
321      LogUtil.error(`${TAG} failed to get clickResponseTime, because ${JSON.stringify(err)}`);
322    });
323
324    await config.ignoreRepeatClick.get().then((data) => {
325      LogUtil.info(`${TAG} get ignoreRepeatClick success: ${data}`);
326      this.ignoreRepeatClickIsOn = data;
327    }).catch((err: object) => {
328      LogUtil.error(`${TAG} failed to get ignoreRepeatClick, because ${JSON.stringify(err)}`);
329    });
330
331    await config.repeatClickInterval.get().then((data) => {
332      LogUtil.info(`${TAG} get daltonizationColorFilter success: ${data}`);
333      if (data === 'Shortest') {
334        this.setIgnoreRepeatClickTime = 0;
335        this.ignoreRepeatClickTimeText = (Object)($r('app.string.shortest'));
336      } else if (data === 'Short') {
337        this.setIgnoreRepeatClickTime = 25;
338        this.ignoreRepeatClickTimeText = (Object)($r('app.string.short'));
339      } else if (data === 'Medium') {
340        this.setIgnoreRepeatClickTime = 50;
341        this.ignoreRepeatClickTimeText = (Object)($r('app.string.centre'));
342      } else if (data === 'Long') {
343        this.setIgnoreRepeatClickTime = 75;
344        this.ignoreRepeatClickTimeText = (Object)($r('app.string.long'));
345      } else {
346        this.setIgnoreRepeatClickTime = 100;
347        this.ignoreRepeatClickTimeText = (Object)($r('app.string.longest'));
348      }
349    }).catch((err: BusinessError) => {
350      LogUtil.error(`${TAG} failed to get ignoreRepeatClickTime, because ${JSON.stringify(err)}`);
351    });
352  }
353
354  aboutToAppear(): void {
355    LogUtil.info(`${TAG} aboutToAppear in`);
356    this.getColorCorrectionStateAndTarget();
357
358    LogUtil.info(`${TAG} aboutToAppear out`);
359  }
360
361  aboutToDisappear(): void {
362    LogUtil.info(`${TAG} aboutToDisappear`);
363  }
364}
365
366@CustomDialog
367struct SelectAbilityScalingInformation {
368  controller?: CustomDialogController;
369  @Link clickResponseTimeText: string;
370  @Link checked: config.ClickResponseTime;
371  @Link allClickResponseTimeList: Array<config.ClickResponseTime>;
372
373  build() {
374    Column() {
375      Column() {
376        Text($r('app.string.click_duration'))
377          .fontFamily('HarmonyHeiTi')
378          .fontSize($r('sys.float.ohos_id_text_size_headline8'))
379          .fontWeight(FontWeight.Medium)
380          .height($r('app.float.wh_value_56'))
381          .alignSelf(ItemAlign.Start);
382
383        List() {
384          ForEach(this.allClickResponseTimeList, (item: config.ClickResponseTime, index) => {
385            ListItem() {
386              Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
387                Text((item === BASIC_SUSTAIN_DURATION_SHORT) ? $r('app.string.default_short') :
388                  ((item === BASIC_SUSTAIN_DURATION_CENTRE) ? $r('app.string.centre') : $r('app.string.long')))
389                  .fontFamily('HarmonyHeiTi')
390                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
391                  .fontWeight(FontWeight.Medium);
392
393                Radio({ value: '', group: 'radioGroup' })
394                  .checked(this.checked === item ? true : false)
395                  .height($r('app.float.wh_value_24'))
396                  .width($r('app.float.wh_value_24'))
397                  .onChange((value: boolean) => {
398                    if (value) {
399                      this.controller?.close();
400                      this.setAbilityText(item);
401                      this.setColorCorrectionStatusText(item);
402                      this.checked = item;
403                    }
404                  })
405              }
406              .height($r('app.float.wh_value_48'))
407            }
408            .height($r('app.float.wh_value_48'))
409          })
410        }
411
412        Text($r('app.string.Cancel_Animation'))
413          .fontSize($r('sys.float.ohos_id_text_size_button1'))
414          .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
415          .alignSelf(ItemAlign.Center)
416          .width($r('app.float.wh_value_40'))
417          .height($r('app.float.wh_value_40'))
418          .margin({ top: $r('app.float.distance_8') })
419          .onClick(() => {
420            this.controller?.close();
421          })
422      }
423      .padding({
424        left: $r('app.float.padding_24'),
425        right: $r('app.float.padding_24'),
426      })
427      .width(ConfigData.WH_100_100)
428      .alignItems(HorizontalAlign.Center)
429      .backgroundColor($r('app.color.white_bg_color'))
430      .borderRadius($r('app.float.radius_24'));
431    }
432    .width(ConfigData.WH_100_100)
433    .padding({ left: $r('app.float.distance_12'), right: $r('app.float.distance_12') });
434  }
435
436  setAbilityText(ability: config.ClickResponseTime): void {
437    LogUtil.info(`${TAG} set ability text ${ability}`);
438    AccessibilitySettingModel.accessibilityClickResponseTimeSet(ability);
439  }
440
441  setColorCorrectionStatusText(text: string): void {
442    if (text === BASIC_SUSTAIN_DURATION_SHORT) {
443      this.clickResponseTimeText = (Object)($r('app.string.default_short'));
444    } else if (text === BASIC_SUSTAIN_DURATION_CENTRE) {
445      this.clickResponseTimeText = (Object)($r('app.string.centre'));
446    } else {
447      this.clickResponseTimeText = (Object)($r('app.string.long'));
448    }
449  }
450}