1/*
2 * Copyright (c) 2023-2024 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 */
15import { LengthMetrics } from '@ohos.arkui.node';
16import common from '@ohos.app.ability.common';
17
18export enum CounterType {
19  LIST = 0,
20  COMPACT = 1,
21  INLINE = 2,
22  INLINE_DATE = 3
23}
24
25enum FocusText {
26  NONE,
27  TEXT1,
28  TEXT2,
29  TEXT3,
30}
31
32export class CommonOptions {
33  public focusable?: boolean;
34  public step?: number;
35  public onHoverIncrease?: (isHover: boolean) => void;
36  public onHoverDecrease?: (isHover: boolean) => void;
37}
38
39export class InlineStyleOptions extends CommonOptions {
40  public value?: number;
41  public min?: number;
42  public max?: number;
43  public textWidth?: number;
44  public onChange?: (value: number) => void;
45}
46
47export class NumberStyleOptions extends InlineStyleOptions {
48  public label?: ResourceStr;
49  public onFocusIncrease?: () => void;
50  public onFocusDecrease?: () => void;
51  public onBlurIncrease?: () => void;
52  public onBlurDecrease?: () => void;
53}
54
55export class DateData {
56  public year: number;
57  public month: number;
58  public day: number;
59
60  constructor(year: number, month: number, day: number) {
61    this.year = year;
62    this.month = month;
63    this.day = day;
64  }
65
66  toString(): string {
67    let date = this.year.toString() + '-';
68    let month = this.month < 10 ? '0' + this.month.toString() : this.month.toString();
69    date += month + '-';
70    let day = this.day < 10 ? '0' + this.day.toString() : this.day.toString();
71    date += day;
72    return date;
73  }
74}
75
76export class DateStyleOptions extends CommonOptions {
77  public year?: number;
78  public month?: number;
79  public day?: number;
80  public onDateChange?: (date: DateData) => void;
81}
82
83export class CounterOptions {
84  public type: CounterType;
85  public direction?: Direction;
86  public numberOptions?: NumberStyleOptions;
87  public inlineOptions?: InlineStyleOptions;
88  public dateOptions?: DateStyleOptions;
89}
90
91class CounterResource {
92  // counter color
93  public static readonly BUTTON_BACKGROUD_COLOR = $r('sys.color.ohos_id_color_button_normal');
94  public static readonly BUTTON_ICON_COLOR = $r('sys.color.ohos_id_color_primary');
95  public static readonly BUTTON_BORDER_FOCUSED_COLOR = $r('sys.color.ohos_id_color_focused_outline');
96  public static readonly COUNTER_TEXT_COLOR = $r('sys.color.ohos_id_color_text_primary');
97  public static readonly COUNTER_BORDER_COLOR = $r('sys.color.ohos_id_color_component_normal');
98  // button icon
99  public static readonly BUTTON_ADD_ICON = $r("sys.media.ohos_ic_public_add");
100  public static readonly BUTTON_SUB_ICON = $r("sys.media.ohos_ic_public_minus");
101  public static readonly BUTTON_ARROW_UP = $r('sys.media.ohos_ic_public_arrow_up');
102  public static readonly BUTTON_ARROW_DOWN = $r('sys.media.ohos_ic_public_arrow_down');
103  // counter size
104  public static readonly BUTTON_BORDER_FOCUSED_WIDTH = '2vp';
105  public static readonly BUTTON_BORDER_BLUR_WIDTH = '0vp';
106  public static readonly COUNTER_BORDER_WIDTH = '1vp';
107  public static readonly COUNTER_BORDER_WIDTH_NUMBER = 1;
108  public static readonly COUNTER_LIST_LABEL_SIZE = $r('sys.float.ohos_id_text_size_body1');
109  public static readonly COUNTER_LIST_NUMBER_SIZE = $r('sys.float.ohos_id_text_size_body1');
110  public static readonly COUNTER_COMPACT_LABEL_SIZE = $r('sys.float.ohos_id_text_size_body2');
111  public static readonly COUNTER_NUMBER_SIZE = $r('sys.float.ohos_id_text_size_body1');
112  public static readonly COUNTER_LIST_LEFT_PADDING = $r('sys.float.ohos_id_default_padding_start');
113  public static readonly COUNTER_LIST_RIGHT_PADDING = $r('sys.float.ohos_id_default_padding_end');
114  public static readonly COUNTER_LIST_PADDING = 12;
115  public static readonly COUNTER_LIST_HEIGHT = '48vp';
116  public static readonly COUNTER_LIST_BUTTON_ICON_SIZE = '20vp';
117  public static readonly COUNTER_LIST_BUTTON_SIZE = '32vp';
118  public static readonly COUNTER_LIST_BUTTON_RADIUS = '16vp';
119  public static readonly COUNTER_LIST_BUTTON_TEXT_DISTANCE = '8vp';
120  public static readonly COUNTER_LIST_BUTTON_TEXT_MARGIN = 8;
121  public static readonly COUNTER_LIST_FOCUS_BORDER_SIZE = '30vp';
122  public static readonly COUNTER_LIST_FOCUS_BORDER_RADIUS = '15vp';
123  public static readonly COUNTER_LIST_BUTTON_HOT_SPOT_X = '-8vp';
124  public static readonly COUNTER_LIST_BUTTON_HOT_SPOT_Y = '-8vp';
125  public static readonly COUNTER_COMPACT_BUTTON_ICON_SIZE = '16vp';
126  public static readonly COUNTER_COMPACT_BUTTON_SIZE = '24vp';
127  public static readonly COUNTER_COMPACT_BUTTON_RADIUS = '12vp';
128  public static readonly COUNTER_COMPACT_BUTTON_TEXT_DISTANCE = '10vp';
129  public static readonly COUNTER_COMPACT_BUTTON_TEXT_MARGIN = 10;
130  public static readonly COUNTER_COMPACT_CONTAINER_HEIGHT = '28vp';
131  public static readonly COUNTER_COMPACT_CONTAINER_RADIUS = '14vp';
132  public static readonly COUNTER_COMPACT_CONTAINER_LABEL_DISTANCE = '8vp';
133  public static readonly COUNTER_COMPACT_FOCUS_BORDER_SIZE = '22vp';
134  public static readonly COUNTER_COMPACT_FOCUS_BORDER_RADIUS = '11vp';
135  public static readonly COUNTER_INLINE_BUTTON_ICON_WIDTH = '24vp';
136  public static readonly COUNTER_INLINE_BUTTON_ICON_HEIGHT = '12vp';
137  public static readonly COUNTER_INLINE_BUTTON_TEXT_DISTANCE = '12vp';
138  public static readonly COUNTER_INLINE_CONTAINER_HEIGHT = '32vp';
139  public static readonly COUNTER_INLINE_BUTTON_WIDTH = '32vp';
140  public static readonly COUNTER_INLINE_BUTTON_HEIGHT = '16vp';
141  public static readonly COUNTER_INLINE_RADIUS = '8vp';
142  public static readonly COUNTER_INLINE_FOCUS_BORDER_WIDTH = '28vp';
143  public static readonly COUNTER_INLINE_FOCUS_BORDER_HEIGHT = '13.5vp';
144  public static readonly COUNTER_INLINE_DATE_TEXT_MARGIN = 12;
145  public static readonly COUNTER_INLINE_INPUT_TEXT_MARGIN = 12;
146  public static readonly COUNTER_BUTTON_INITIAL_OPACITY = 1;
147  public static readonly COUNTER_BUTTON_DISABLE_OPACITY = 0.4;
148  public static readonly COUNTER_LABEL_MAX_FONT_SIZE_SCALE = 2;
149  public static readonly COUNTER_NUMBER_MAX_FONT_SIZE_SCALE = 1;
150}
151
152class CounterConstant {
153  public static readonly COUNTER_MAX_YEAR = 5000;
154  public static readonly COUNTER_MIN_YEAR = 1;
155  public static readonly COUNTER_INITIAL_MONTH = 1;
156  public static readonly COUNTER_INITIAL_DAY = 1;
157  public static readonly COUNTER_INITIAL_STEP = 1;
158  public static readonly COUNTER_TEN_NUMBER = 10;
159  public static readonly COUNTER_MIN_MONTH = 1;
160  public static readonly COUNTER_MAX_MONTH = 12;
161  public static readonly COUNTER_MIN_DAY = 1;
162  public static readonly KEYCODE_DPAD_UP = 2012;
163  public static readonly KEYCODE_DPAD_DOWN = 2013;
164  public static readonly KEYCODE_DPAD_LEFT = 2014;
165  public static readonly KEYCODE_DPAD_RIGHT = 2015;
166  public static readonly KEYCODE_MOVE_HOME = 2081;
167  public static readonly KEYCODE_MOVE_END = 2082;
168  public static readonly KEYCODE_TAB = 2049;
169  public static readonly KEYCODE_ESC = 2070;
170  public static readonly COUNTER_MIN_VALUE = 0;
171  public static readonly COUNTER_MAX_VALUE = 999;
172  public static readonly JANUARY = 1;
173  public static readonly FEBRUARY = 2;
174  public static readonly MARCH = 3;
175  public static readonly APRIL = 4;
176  public static readonly MAY = 5;
177  public static readonly JUNE = 6;
178  public static readonly JULY = 7;
179  public static readonly AUGUST = 8;
180  public static readonly SEPTEMBER = 9;
181  public static readonly OCTOBER = 10;
182  public static readonly NOVEMBER = 11;
183  public static readonly DECEMBER = 12;
184  public static readonly BIG_MONTH_DAYS = 31;
185  public static readonly SMALL_MONTH_DAYS = 30;
186  public static readonly FEBRUARY_DAYS = 28;
187  public static readonly AUSPICIOUS_FEBRUARY_DAYS = 29;
188  public static readonly AUSPICIOUS_FOUR = 4;
189  public static readonly AUSPICIOUS_HUNDRED = 100;
190  public static readonly AUSPICIOUS_FOUR_HUNDRED = 400;
191}
192
193@Component
194export struct CounterComponent {
195  @Prop @Watch('onOptionsChange') options: CounterOptions;
196  @State type: number = -1;
197  @State counterDirection: Direction = Direction.Auto;
198  @State choverEffect: HoverEffect = HoverEffect.Auto;
199  @State focusEnable: boolean = true;
200  @State step: number = CounterConstant.COUNTER_INITIAL_STEP;
201  @State inputValue: string = '0';
202  @State inputYear: number = CounterConstant.COUNTER_MIN_YEAR;
203  @State inputMoon: number = 0;
204  @State inputDay: number = 0;
205  @State inputHour: number = 0;
206  @State inputMinute: number = 0;
207  @State inputSecond: number = 0;
208  @State subOpacity: number = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
209  @State addOpacity: number = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
210  @State subBtnStateEffect: boolean = true;
211  @State addBtnStateEffect: boolean = true;
212  @State focusText: number = FocusText.NONE;
213  @State hasFocusText1: boolean = false
214  @State hasFocusText2: boolean = false
215  @State hasFocusText3: boolean = false
216  @State subBtnFocusWidh: string = '0vp'
217  @State addBtnFocusWidh: string = '0vp'
218  @State value: number | undefined = undefined;
219  @State year: number = 0;
220  @State month: number = 0;
221  @State day: number = 0;
222  @State hour: number = 0;
223  @State minute: number = 0;
224  @State second: number = 0;
225  @State subBtnEnabled: boolean = true
226  @State addBtnEnabled: boolean = true
227  @State hasInputText1: boolean = false;
228  @State hasInputText2: boolean = false;
229  @State hasInputText3: boolean = false;
230  @State textWidth: number = 0;
231  @State min: number = CounterConstant.COUNTER_MIN_VALUE;
232  @State max: number = CounterConstant.COUNTER_MAX_VALUE;
233  private maxYear: number = CounterConstant.COUNTER_MAX_YEAR;
234  private minYear: number = CounterConstant.COUNTER_MIN_YEAR;
235  private numberStrList: Array<string> = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'];
236  private onHoverIncrease?: (isHover: boolean) => void;
237  private onHoverDecrease?: (isHover: boolean) => void;
238  private onFocusIncrease?: () => void;
239  private onFocusDecrease?: () => void;
240  private onBlurIncrease?: () => void;
241  private onBlurDecrease?: () => void;
242  private onChange?: (value: number) => void;
243  private onDateChange?: (date: DateData) => void;
244  private timeoutID1: number = -1;
245  private timeoutID2: number = -1;
246  private timeoutID3: number = -1;
247  private numberStyleOptions: NumberStyleOptions;
248  private dateStyleOptions: DateStyleOptions;
249  private inlineStyleOptions: InlineStyleOptions;
250  private timeStamp: number = 0;
251  private hasTextWidth: boolean = false;
252  private controller1: TextInputController = new TextInputController();
253  private controller2: TextInputController = new TextInputController();
254  private controller3: TextInputController = new TextInputController();
255
256  getTextInputFontSize() {
257    let fontSize = this.resourceToVp(CounterResource.COUNTER_NUMBER_SIZE);
258    let uiContext = this.getUIContext();
259    let fontSizeScale = (uiContext.getHostContext() as common.UIAbilityContext)?.config?.fontSizeScale ?? 1;
260    if (fontSizeScale < 1) {
261      return fontSize + 'fp';
262    } else {
263      return fontSize + 'vp';
264    }
265  }
266
267  convertNumberToString(value: number) {
268    if (value >= 0 && value < CounterConstant.COUNTER_TEN_NUMBER) {
269      return this.numberStrList[value];
270    } else {
271      return value.toString();
272    }
273  }
274
275  aboutToAppear(): void {
276    let dateTime = new Date();
277    this.timeStamp = dateTime.getTime();
278    if (this.options !== undefined && this.options !== null) {
279      this.onOptionsChange();
280    }
281  }
282
283  private updateNumberStyleOptions() {
284    if (this.numberStyleOptions.label === undefined) {
285      this.numberStyleOptions.label = '';
286    }
287    if (this.value === undefined) {
288      this.value = this.numberStyleOptions.value !== undefined ? this.numberStyleOptions.value : 0;
289      this.onChange?.(this.value);
290      this.inputValue = this.value.toString();
291    }
292    if (this.numberStyleOptions.min !== undefined) {
293      this.min = this.numberStyleOptions.min;
294    }
295    if (this.numberStyleOptions.max !== undefined) {
296      this.max = this.numberStyleOptions.max;
297    }
298    if (this.min > this.max) {
299      this.min = this.max;
300    }
301    if (this.numberStyleOptions.textWidth !== undefined) {
302      this.textWidth = this.numberStyleOptions.textWidth;
303      if (this.textWidth < 0) {
304        this.textWidth = 0;
305      }
306      this.hasTextWidth = true;
307    }
308    if (this.value <= this.min) {
309      this.value = this.min;
310      this.onChange?.(this.value);
311      this.inputValue = this.value.toString();
312    }
313    if (this.value >= this.max) {
314      this.value = this.max;
315      this.onChange?.(this.value);
316      this.inputValue = this.value.toString();
317    }
318    if (this.numberStyleOptions.step !== undefined) {
319      if (this.numberStyleOptions.step < 1) {
320        this.step = 1
321      } else {
322        this.step = this.numberStyleOptions.step;
323      }
324    }
325    this.updateButtonStatus()
326    this.updateNumberStyleOptionsEvent();
327  }
328
329  private updateNumberStyleOptionsEvent() {
330    if (this.numberStyleOptions.onHoverIncrease !== undefined) {
331      this.onHoverIncrease = this.numberStyleOptions.onHoverIncrease;
332    }
333    if (this.numberStyleOptions.onHoverDecrease !== undefined) {
334      this.onHoverDecrease = this.numberStyleOptions.onHoverDecrease;
335    }
336    if (this.numberStyleOptions.onFocusIncrease !== undefined) {
337      this.onFocusIncrease = this.numberStyleOptions.onFocusIncrease;
338    }
339    if (this.numberStyleOptions.onFocusDecrease !== undefined) {
340      this.onFocusDecrease = this.numberStyleOptions.onFocusDecrease;
341    }
342    if (this.numberStyleOptions.onBlurIncrease !== undefined) {
343      this.onBlurIncrease = this.numberStyleOptions.onBlurIncrease;
344    }
345    if (this.numberStyleOptions.onBlurDecrease !== undefined) {
346      this.onBlurDecrease = this.numberStyleOptions.onBlurDecrease;
347    }
348    if (this.numberStyleOptions.onChange !== undefined) {
349      this.onChange = this.numberStyleOptions.onChange;
350    }
351    if (this.numberStyleOptions.focusable !== undefined) {
352      this.focusEnable = this.numberStyleOptions.focusable;
353    }
354  }
355
356  private updateInlineStyleOptions() {
357    if (this.value === undefined) {
358      this.value = this.inlineStyleOptions.value !== undefined ? this.inlineStyleOptions.value : 0;
359      this.onChange?.(this.value);
360      this.inputValue = this.value.toString();
361    }
362    if (this.inlineStyleOptions.min !== undefined) {
363      this.min = this.inlineStyleOptions.min;
364    }
365    if (this.inlineStyleOptions.max !== undefined) {
366      this.max = this.inlineStyleOptions.max;
367    }
368    if (this.min > this.max) {
369      this.min = this.max;
370    }
371
372    if (this.inlineStyleOptions.textWidth !== undefined) {
373      this.textWidth = this.inlineStyleOptions.textWidth;
374      if (this.textWidth < 0) {
375        this.textWidth = 0;
376      }
377      this.hasTextWidth = true;
378    }
379    if (this.value <= this.min) {
380      this.value = this.min;
381      this.onChange?.(this.value);
382      this.inputValue = this.value.toString();
383    }
384    if (this.value >= this.max) {
385      this.value = this.max;
386      this.onChange?.(this.value);
387      this.inputValue = this.value.toString();
388    }
389    if (this.inlineStyleOptions.step !== undefined) {
390      if (this.inlineStyleOptions.step < 1) {
391        this.step = 1
392      } else {
393        this.step = this.inlineStyleOptions.step;
394      }
395    }
396    this.updateButtonStatus()
397    this.updateInlineStyleOptionsEvent();
398  }
399
400  private updateInlineStyleOptionsEvent() {
401    if (this.inlineStyleOptions.onHoverIncrease !== undefined) {
402      this.onHoverIncrease = this.inlineStyleOptions.onHoverIncrease;
403    }
404    if (this.inlineStyleOptions.onHoverDecrease !== undefined) {
405      this.onHoverDecrease = this.inlineStyleOptions.onHoverDecrease;
406    }
407    if (this.inlineStyleOptions.onChange !== undefined) {
408      this.onChange = this.inlineStyleOptions.onChange;
409    }
410    if (this.inlineStyleOptions.focusable !== undefined) {
411      this.focusEnable = this.inlineStyleOptions.focusable;
412    }
413  }
414
415  private updateDateStyleOptions() {
416    if (this.dateStyleOptions.step !== undefined) {
417      if (this.dateStyleOptions.step < 1) {
418        this.step = 1
419      } else {
420        this.step = Math.floor(this.dateStyleOptions.step);
421      }
422    }
423    if (this.dateStyleOptions.onHoverIncrease !== undefined) {
424      this.onHoverIncrease = this.dateStyleOptions.onHoverIncrease;
425    }
426    if (this.dateStyleOptions.onHoverDecrease !== undefined) {
427      this.onHoverDecrease = this.dateStyleOptions.onHoverDecrease;
428    }
429    if (this.dateStyleOptions.year !== undefined &&
430      this.dateStyleOptions.year >= this.minYear &&
431      this.dateStyleOptions.year <= this.maxYear) {
432      if (this.year === 0) {
433        this.year = this.dateStyleOptions.year;
434      }
435    } else {
436      this.year = CounterConstant.COUNTER_MIN_YEAR;
437    }
438    if (this.dateStyleOptions.month !== undefined &&
439      this.dateStyleOptions.month <= CounterConstant.COUNTER_MAX_MONTH &&
440      this.dateStyleOptions.month >= CounterConstant.COUNTER_MIN_MONTH) {
441      if (this.month === 0) {
442        this.month = this.dateStyleOptions.month;
443      }
444    } else {
445      this.month = CounterConstant.COUNTER_INITIAL_MONTH;
446    }
447    if (this.dateStyleOptions.day !== undefined &&
448      this.dateStyleOptions.day <= this.getDayNumber() &&
449      this.dateStyleOptions.day >= CounterConstant.COUNTER_MIN_DAY) {
450      if (this.day === 0) {
451        this.day = this.dateStyleOptions.day;
452      }
453    } else {
454      this.day = CounterConstant.COUNTER_INITIAL_DAY;
455    }
456    if (this.dateStyleOptions.onDateChange !== undefined) {
457      this.onDateChange = this.dateStyleOptions.onDateChange;
458    }
459    if (this.dateStyleOptions.focusable !== undefined) {
460      this.focusEnable = this.dateStyleOptions.focusable;
461    }
462    this.updateDay();
463  }
464
465  private onOptionsChange() {
466    this.type = this.options.type;
467    if (this.options.direction) {
468      this.counterDirection = this.options.direction;
469    } else {
470      this.counterDirection = Direction.Auto;
471    }
472
473    if (this.type === CounterType.LIST ||
474      this.type === CounterType.COMPACT) {
475      this.numberStyleOptions = this.options.numberOptions;
476      this.updateNumberStyleOptions();
477    } else if (this.type === CounterType.INLINE) {
478      this.inlineStyleOptions = this.options.inlineOptions;
479      this.updateInlineStyleOptions();
480    } else if (this.type === CounterType.INLINE_DATE) {
481      let options = this.options.dateOptions;
482      options.year = options.year ? options.year : CounterConstant.COUNTER_MIN_YEAR;
483      options.month = options.month ? options.month : CounterConstant.COUNTER_MIN_MONTH;
484      options.day = options.day ? options.day : CounterConstant.COUNTER_MIN_DAY;
485      this.dateStyleOptions = options;
486      this.updateDateStyleOptions();
487    } else {
488
489    }
490  }
491
492  private subValue(): void {
493    if (this.subBtnStateEffect) {
494      this.value -= this.step;
495    }
496    if (!this.addBtnStateEffect) {
497      this.addBtnStateEffect = true;
498      this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
499      this.addBtnEnabled = true;
500    }
501    if (this.value <= this.min) {
502      this.value = this.min;
503      this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
504      this.subBtnStateEffect = false;
505      this.subBtnEnabled = false;
506    } else {
507      if (this.subOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
508        this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
509      }
510      if (!this.subBtnStateEffect) {
511        this.subBtnStateEffect = true;
512      }
513      if (!this.subBtnEnabled) {
514        this.subBtnEnabled = true;
515      }
516    }
517    this.focusText1();
518  }
519
520  private focusText1() {
521    if (this.type === CounterType.INLINE) {
522      if (this.focusText === FocusText.NONE) {
523        this.focusText = FocusText.TEXT1;
524        this.hasFocusText1 = true;
525        this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
526      }
527    }
528  }
529
530  private addValue(): void {
531    if (this.addBtnStateEffect) {
532      this.value += this.step;
533    }
534
535    if (!this.subBtnStateEffect) {
536      this.subBtnStateEffect = true;
537      this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
538      this.subBtnEnabled = true;
539    }
540    if (this.value >= this.max) {
541      this.value = this.max;
542      this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
543      this.addBtnStateEffect = false;
544      this.addBtnEnabled = false;
545    } else {
546      if (this.addOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
547        this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
548      }
549      if (!this.addBtnStateEffect) {
550        this.addBtnStateEffect = true;
551      }
552      if (!this.addBtnEnabled) {
553        this.addBtnEnabled = true;
554      }
555    }
556
557    this.focusText1();
558  }
559
560  private getDayNumber(): number {
561    switch (this.month) {
562      case CounterConstant.JANUARY:
563      case CounterConstant.MARCH:
564      case CounterConstant.MAY:
565      case CounterConstant.JULY:
566      case CounterConstant.AUGUST:
567      case CounterConstant.OCTOBER:
568      case CounterConstant.DECEMBER:
569        return CounterConstant.BIG_MONTH_DAYS;
570        break;
571      case CounterConstant.APRIL:
572      case CounterConstant.JUNE:
573      case CounterConstant.SEPTEMBER:
574      case CounterConstant.NOVEMBER:
575        return CounterConstant.SMALL_MONTH_DAYS;
576        break;
577      case CounterConstant.FEBRUARY:
578        if ((this.year % CounterConstant.AUSPICIOUS_FOUR === 0 &&
579          this.year % CounterConstant.AUSPICIOUS_HUNDRED !== 0) ||
580          this.year % CounterConstant.AUSPICIOUS_FOUR_HUNDRED === 0) {
581          return CounterConstant.AUSPICIOUS_FEBRUARY_DAYS;
582        } else {
583          return CounterConstant.FEBRUARY_DAYS;
584        }
585        break;
586      default:
587        break;
588    }
589  }
590
591  private subDate(): void {
592    if (this.focusText === FocusText.TEXT1) {
593      if (this.subBtnStateEffect) {
594        this.inputYear = this.year;
595        this.year -= this.step;
596        if (!this.hasFocusText1) {
597          this.hasFocusText1 = true;
598        }
599      }
600      if (!this.addBtnStateEffect) {
601        this.addBtnStateEffect = true;
602        this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
603        this.addBtnEnabled = true;
604      }
605      if (this.year <= this.minYear) {
606        this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
607        this.subBtnStateEffect = false;
608        this.subBtnEnabled = false;
609      } else {
610        if (this.subOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
611          this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
612        }
613        if (!this.subBtnStateEffect) {
614          this.subBtnStateEffect = true;
615        }
616        if (!this.subBtnEnabled) {
617          this.subBtnEnabled = true;
618        }
619      }
620    } else if (this.focusText === FocusText.TEXT2) {
621      this.month -= this.step % CounterConstant.COUNTER_MAX_MONTH;
622      if (this.month < CounterConstant.COUNTER_MIN_MONTH) {
623        this.month += CounterConstant.COUNTER_MAX_MONTH;
624      }
625      if (!this.hasFocusText2) {
626        this.hasFocusText2 = true;
627      }
628    } else if (this.focusText === FocusText.TEXT3) {
629      this.day -= this.step % this.getDayNumber();
630      if (this.day < CounterConstant.COUNTER_MIN_DAY) {
631        this.day += this.getDayNumber();
632      }
633      if (!this.hasFocusText3) {
634        this.hasFocusText3 = true;
635      }
636    } else {
637      this.focusDayWitdhSub();
638    }
639  }
640
641  private focusDayWitdhSub() {
642    this.focusText = FocusText.TEXT3;
643    this.hasFocusText3 = true;
644    this.day -= this.step % this.getDayNumber();
645    if (this.day < CounterConstant.COUNTER_MIN_DAY) {
646      this.day += this.getDayNumber();
647    }
648    this.focusWithTarget('DateTextInput3' + this.timeStamp.toString());
649  }
650
651  private addDate(): void {
652    if (this.focusText === FocusText.TEXT1) {
653      if (this.addBtnStateEffect) {
654        this.inputYear = this.year;
655        this.year += this.step;
656        if (!this.hasFocusText1) {
657          this.hasFocusText1 = true;
658        }
659      }
660      if (!this.subBtnStateEffect) {
661        this.subBtnStateEffect = true;
662        this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
663        this.subBtnEnabled = true;
664      }
665      if (this.year >= this.maxYear) {
666        this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
667        this.addBtnStateEffect = false;
668        this.addBtnEnabled = false;
669      } else {
670        if (this.addOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
671          this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
672        }
673        if (!this.addBtnStateEffect) {
674          this.addBtnStateEffect = true;
675        }
676        if (!this.addBtnEnabled) {
677          this.addBtnEnabled = true;
678        }
679      }
680    } else if (this.focusText === FocusText.TEXT2) {
681      this.month += this.step % CounterConstant.COUNTER_MAX_MONTH;
682      if (this.month > CounterConstant.COUNTER_MAX_MONTH) {
683        this.month -= CounterConstant.COUNTER_MAX_MONTH;
684      }
685      if (!this.hasFocusText2) {
686        this.hasFocusText2 = true;
687      }
688    } else if (this.focusText === FocusText.TEXT3) {
689      this.day += this.step % this.getDayNumber();
690      if (this.day > this.getDayNumber()) {
691        this.day -= this.getDayNumber();
692      }
693      if (!this.hasFocusText3) {
694        this.hasFocusText3 = true;
695      }
696    } else {
697      this.focusDayWithAdd();
698    }
699  }
700
701  private focusDayWithAdd() {
702    this.focusText = FocusText.TEXT3;
703    this.hasFocusText3 = true;
704    this.day += this.step % this.getDayNumber();
705    if (this.day > this.getDayNumber()) {
706      this.day -= this.getDayNumber();
707    }
708    this.focusWithTarget('DateTextInput3' + this.timeStamp.toString());
709  }
710
711  private updateInlineEnableSate() {
712    if (this.value >= this.max) {
713      this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
714      this.addBtnStateEffect = false;
715      this.addBtnEnabled = false;
716    } else {
717      this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
718      this.addBtnStateEffect = true;
719      this.addBtnEnabled = true;
720    }
721    if (this.value <= this.min) {
722      this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
723      this.subBtnStateEffect = false;
724      this.subBtnEnabled = false;
725    } else {
726      this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
727      this.subBtnStateEffect = true;
728      this.subBtnEnabled = true;
729    }
730  }
731
732  private updateDateEnableSate() {
733    if (this.year === this.maxYear && this.focusText === FocusText.TEXT1) {
734      this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
735      this.addBtnStateEffect = false;
736      this.addBtnEnabled = false;
737    } else {
738      if (this.addOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
739        this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
740      }
741      if (!this.addBtnStateEffect) {
742        this.addBtnStateEffect = true;
743      }
744      if (!this.addBtnEnabled) {
745        this.addBtnEnabled = true;
746      }
747    }
748    if (this.year === this.minYear && this.focusText === FocusText.TEXT1) {
749      this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
750      this.subBtnStateEffect = false;
751      this.subBtnEnabled = false;
752    } else {
753      if (this.subOpacity === CounterResource.COUNTER_BUTTON_DISABLE_OPACITY) {
754        this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
755      }
756      if (!this.subBtnStateEffect) {
757        this.subBtnStateEffect = true;
758      }
759      if (!this.subBtnEnabled) {
760        this.subBtnEnabled = true;
761      }
762    }
763  }
764
765  private updateDay() {
766    if (this.day > this.getDayNumber()) {
767      this.day = this.getDayNumber();
768    }
769  }
770
771  private resetFocusText() {
772    this.focusText = FocusText.NONE;
773    this.hasFocusText1 = false;
774    this.hasFocusText2 = false;
775    this.hasFocusText3 = false;
776  }
777
778  private resetFocusButton() {
779    if (this.addBtnFocusWidh === CounterResource.BUTTON_BORDER_FOCUSED_WIDTH) {
780      this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
781      this.onBlurIncrease && this.onBlurIncrease();
782    }
783    if (this.subBtnFocusWidh === CounterResource.BUTTON_BORDER_FOCUSED_WIDTH) {
784      this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
785      this.onBlurDecrease && this.onBlurDecrease();
786    }
787  }
788
789  private homeFocusText() {
790    this.focusWithTarget('DateTextInput1' + this.timeStamp.toString());
791  }
792
793  private endFocusText() {
794    this.focusWithTarget('DateTextInput3' + this.timeStamp.toString());
795  }
796
797  private homeFirstValue() {
798    this.value = this.min;
799    if (!this.addBtnStateEffect) {
800      this.addBtnStateEffect = true;
801      this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
802      this.addBtnEnabled = true;
803    }
804  }
805
806  private endLastValue() {
807    this.value = this.max;
808    if (!this.subBtnStateEffect) {
809      this.subBtnStateEffect = true;
810      this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
811      this.subBtnEnabled = true;
812    }
813  }
814
815  private updateButtonStatus() {
816    if (this.value <= this.min) {
817      if (!this.addBtnStateEffect && this.max != this.min) {
818        this.addBtnStateEffect = true;
819        this.addOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
820        this.addBtnEnabled = true;
821      }
822      this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
823      this.subBtnStateEffect = false;
824      this.subBtnEnabled = false;
825    }
826    if (this.value >= this.max) {
827      if (!this.subBtnStateEffect && this.max != this.min) {
828        this.subBtnStateEffect = true;
829        this.subOpacity = CounterResource.COUNTER_BUTTON_INITIAL_OPACITY;
830        this.subBtnEnabled = true;
831      }
832      this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
833      this.addBtnStateEffect = false;
834      this.addBtnEnabled = false;
835    }
836  }
837
838  private getValue() {
839    if (this.inputValue == undefined) {
840      this.inputValue = ''
841    }
842    return this.hasInputText1 ? this.inputValue : this.value.toString();
843  }
844
845  private getValueLength() {
846    return this.getValue().length > 0 ? this.getValue().length : 1;
847  }
848
849  private getYear() {
850    let year: string = this.year.toString();
851    if (year.length === 1) {
852      year = '000' + year;
853    } else if (year.length === 2) {
854      year = '00' + year;
855    } else if (year.length === 3) {
856      year = '0' + year;
857    } else {
858      year = year;
859    }
860    return year;
861  }
862
863  private focusWithTarget(key: string) {
864    setTimeout(() => {
865      var res = focusControl.requestFocus(key);
866      if (res) {
867        console.log('Request success');
868      } else {
869        console.log('Request failed');
870      }
871    });
872  }
873
874  private focusCurrentText(text: FocusText) {
875    if (text === FocusText.TEXT1) {
876      if (this.focusText === FocusText.NONE) {
877        this.focusText = FocusText.TEXT1;
878      }
879      if (!this.hasFocusText1) {
880        this.hasFocusText1 = true;
881      }
882    } else if (text === FocusText.TEXT2) {
883      if (this.focusText === FocusText.NONE) {
884        this.focusText = FocusText.TEXT2;
885      }
886      if (!this.hasFocusText2) {
887        this.hasFocusText2 = true;
888      }
889    } else if (text === FocusText.TEXT3) {
890      if (this.focusText === FocusText.NONE) {
891        this.focusText = FocusText.TEXT3;
892      }
893      if (!this.hasFocusText3) {
894        this.hasFocusText3 = true;
895      }
896    } else {
897
898    }
899  }
900
901  private getMaxLength() {
902    if (this.max.toString().length > this.min.toString().length) {
903      return this.max.toString().length + 1;
904    } else {
905      return this.min.toString().length + 1;
906    }
907  }
908
909  private resourceToVp(value: Resource): number {
910    try {
911      if ((value as Resource).id !== -1) {
912        return px2vp(getContext(this).resourceManager.getNumber((value as Resource).id))
913      } else {
914        return px2vp(getContext(this)
915          .resourceManager
916          .getNumberByName(((value.params as string[])[0]).split('.')[2]))
917      }
918    } catch (error) {
919      return CounterResource.COUNTER_LIST_PADDING
920    }
921  }
922
923  build() {
924    if (this.type === CounterType.LIST) {
925      RelativeContainer() {
926        Text(this.numberStyleOptions.label)
927          .direction(this.counterDirection)
928          .fontSize(CounterResource.COUNTER_LIST_LABEL_SIZE)
929          .maxFontScale(CounterResource.COUNTER_LABEL_MAX_FONT_SIZE_SCALE);
930          .fontColor(CounterResource.COUNTER_TEXT_COLOR)
931          .margin({
932            start: LengthMetrics.vp(this.resourceToVp(CounterResource.COUNTER_LIST_LEFT_PADDING))
933          })
934          .alignRules({
935            center: { anchor: '__container__', align: VerticalAlign.Center },
936            start: { anchor: '__container__', align: HorizontalAlign.Start },
937            end: { anchor: 'Row1', align: HorizontalAlign.Start }
938          })
939          .id('Text')
940        Row() {
941          Stack() {
942            Image(CounterResource.BUTTON_SUB_ICON)
943              .direction(this.counterDirection)
944              .width(CounterResource.COUNTER_LIST_BUTTON_ICON_SIZE)
945              .height(CounterResource.COUNTER_LIST_BUTTON_ICON_SIZE)
946              .fillColor(CounterResource.BUTTON_ICON_COLOR)
947              .opacity(this.subOpacity)
948            Button({ type: ButtonType.Circle, stateEffect: this.subBtnStateEffect })
949              .direction(this.counterDirection)
950              .width(CounterResource.COUNTER_LIST_BUTTON_SIZE)
951              .height(CounterResource.COUNTER_LIST_BUTTON_SIZE)
952              .responseRegion({
953                x: CounterResource.COUNTER_LIST_BUTTON_HOT_SPOT_X,
954                y: CounterResource.COUNTER_LIST_BUTTON_HOT_SPOT_Y,
955                width: '150%',
956                height: '150%'
957              })
958              .groupDefaultFocus(true)
959              .backgroundColor(CounterResource.BUTTON_BACKGROUD_COLOR)
960              .opacity(this.subOpacity)
961              .enabled(this.subBtnEnabled)
962              .key('ListSubButton' + this.timeStamp.toString())
963              .onKeyEvent((event: KeyEvent) => {
964                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
965                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
966                  this.resetFocusButton();
967                  event.stopPropagation();
968                }
969                if (event.type === KeyType.Down &&
970                  event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
971                  event.stopPropagation();
972                  this.homeFirstValue();
973                  this.focusWithTarget('ListAddButton' + this.timeStamp.toString());
974                }
975                if (event.type === KeyType.Down &&
976                  event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
977                  event.stopPropagation();
978                  if (this.addBtnStateEffect) {
979                    this.addBtnStateEffect = false;
980                    this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
981                    this.addBtnEnabled = false;
982                  }
983                  this.endLastValue();
984                  this.focusWithTarget('ListAddButton' + this.timeStamp.toString());
985                }
986              })
987              .onClick((event: ClickEvent) => {
988                this.subValue();
989                this.onChange?.(this.value);
990                if (event.source === SourceType.Mouse ||
991                  event.source === SourceType.TouchScreen) {
992                  this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
993                }
994              })
995              .gesture(
996                LongPressGesture({ repeat: true })
997                  .onAction((event: GestureEvent) => {
998                    if (event.repeat) {
999                      this.subValue();
1000                      this.onChange?.(this.value);
1001                    }
1002                    this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1003                  })
1004              )
1005              .hoverEffect(this.choverEffect)
1006              .onHover((isHover: boolean) => {
1007                this.onHoverDecrease && this.onHoverDecrease(isHover);
1008              })
1009              .focusable(this.focusEnable)
1010              .onFocus(() => {
1011                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1012                this.onFocusDecrease && this.onFocusDecrease();
1013                this.updateButtonStatus();
1014              })
1015              .onBlur(() => {
1016                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1017                this.onBlurDecrease && this.onBlurDecrease();
1018              })
1019          }
1020          .direction(this.counterDirection)
1021          .width(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1022          .height(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1023          .borderRadius(CounterResource.COUNTER_LIST_BUTTON_RADIUS)
1024          .borderWidth(this.subBtnFocusWidh)
1025          .borderColor(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1026          .clip(true)
1027
1028          if (this.hasTextWidth) {
1029            Text(this.value.toString())
1030              .direction(this.counterDirection)
1031              .width(this.textWidth.toString())
1032              .textAlign(TextAlign.Center)
1033              .fontSize(CounterResource.COUNTER_LIST_NUMBER_SIZE)
1034              .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
1035              .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1036              .margin({
1037                start: LengthMetrics.vp(CounterResource.COUNTER_LIST_BUTTON_TEXT_MARGIN),
1038                end: LengthMetrics.vp(CounterResource.COUNTER_LIST_BUTTON_TEXT_MARGIN)
1039              })
1040          } else {
1041            Text(this.value.toString())
1042              .direction(this.counterDirection)
1043              .textAlign(TextAlign.Center)
1044              .fontSize(CounterResource.COUNTER_LIST_NUMBER_SIZE)
1045              .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
1046              .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1047              .margin({
1048                start: LengthMetrics.vp(CounterResource.COUNTER_LIST_BUTTON_TEXT_MARGIN),
1049                end: LengthMetrics.vp(CounterResource.COUNTER_LIST_BUTTON_TEXT_MARGIN)
1050              })
1051          }
1052
1053          Stack() {
1054            Image(CounterResource.BUTTON_ADD_ICON)
1055              .direction(this.counterDirection)
1056              .width(CounterResource.COUNTER_LIST_BUTTON_ICON_SIZE)
1057              .height(CounterResource.COUNTER_LIST_BUTTON_ICON_SIZE)
1058              .fillColor(CounterResource.BUTTON_ICON_COLOR)
1059              .opacity(this.addOpacity)
1060            Button({ type: ButtonType.Circle, stateEffect: this.addBtnStateEffect })
1061              .direction(this.counterDirection)
1062              .width(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1063              .height(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1064              .responseRegion({
1065                x: CounterResource.COUNTER_LIST_BUTTON_HOT_SPOT_X,
1066                y: CounterResource.COUNTER_LIST_BUTTON_HOT_SPOT_Y,
1067                width: '150%',
1068                height: '150%'
1069              })
1070              .backgroundColor(CounterResource.BUTTON_BACKGROUD_COLOR)
1071              .opacity(this.addOpacity)
1072              .enabled(this.addBtnEnabled)
1073              .key('ListAddButton' + this.timeStamp.toString())
1074              .onKeyEvent((event: KeyEvent) => {
1075                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH
1076                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1077                  this.resetFocusButton();
1078                  event.stopPropagation();
1079                }
1080                if (event.type === KeyType.Down &&
1081                  event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1082                  event.stopPropagation();
1083                  this.homeFirstValue();
1084                  if (this.subBtnStateEffect) {
1085                    this.subBtnStateEffect = false;
1086                    this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
1087                    this.subBtnEnabled = false;
1088                  }
1089                  this.focusWithTarget('ListAddButton' + this.timeStamp.toString());
1090                }
1091                if (event.type === KeyType.Down &&
1092                  event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1093                  event.stopPropagation();
1094                  this.endLastValue();
1095                  this.focusWithTarget('ListSubButton' + this.timeStamp.toString());
1096                }
1097              })
1098              .onClick((event: ClickEvent) => {
1099                this.addValue();
1100                this.onChange?.(this.value);
1101                if (event.source === SourceType.Mouse ||
1102                  event.source === SourceType.TouchScreen) {
1103                  this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1104                }
1105              })
1106              .gesture(
1107                LongPressGesture({ repeat: true })
1108                  .onAction((event: GestureEvent) => {
1109                    if (event.repeat) {
1110                      this.addValue();
1111                      this.onChange?.(this.value);
1112                    }
1113                    this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1114                  })
1115              )
1116              .hoverEffect(this.choverEffect)
1117              .onHover((isHover: boolean) => {
1118                this.onHoverIncrease && this.onHoverIncrease(isHover);
1119              })
1120              .focusable(this.focusEnable)
1121              .onFocus(() => {
1122                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1123                this.onFocusIncrease && this.onFocusIncrease();
1124                this.updateButtonStatus();
1125              })
1126              .onBlur(() => {
1127                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1128                this.onBlurIncrease && this.onBlurIncrease();
1129              })
1130          }
1131          .direction(this.counterDirection)
1132          .width(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1133          .height(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1134          .borderRadius(CounterResource.COUNTER_LIST_BUTTON_RADIUS)
1135          .borderWidth(this.addBtnFocusWidh)
1136          .borderColor(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1137          .clip(true)
1138        }
1139        .direction(this.counterDirection)
1140        .height(CounterResource.COUNTER_LIST_BUTTON_SIZE)
1141        .margin({
1142          end: LengthMetrics.vp(this.resourceToVp(CounterResource.COUNTER_LIST_RIGHT_PADDING))
1143        })
1144        .alignRules({
1145          center: { anchor: '__container__', align: VerticalAlign.Center },
1146          end: { anchor: '__container__', align: HorizontalAlign.End }
1147        })
1148        .tabIndex(0)
1149        .id('Row1')
1150      }
1151      .direction(this.counterDirection)
1152      .width('100%')
1153      .height(CounterResource.COUNTER_LIST_HEIGHT)
1154    } else if (this.type === CounterType.COMPACT) {
1155      Column() {
1156        Row() {
1157          Stack() {
1158            Image(CounterResource.BUTTON_SUB_ICON)
1159              .direction(this.counterDirection)
1160              .width(CounterResource.COUNTER_COMPACT_BUTTON_ICON_SIZE)
1161              .height(CounterResource.COUNTER_COMPACT_BUTTON_ICON_SIZE)
1162              .fillColor(CounterResource.BUTTON_ICON_COLOR)
1163              .opacity(this.subOpacity)
1164            Button({ type: ButtonType.Circle, stateEffect: this.subBtnStateEffect })
1165              .direction(this.counterDirection)
1166              .width(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1167              .height(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1168              .backgroundColor(CounterResource.BUTTON_BACKGROUD_COLOR)
1169              .opacity(this.subOpacity)
1170              .enabled(this.subBtnEnabled)
1171              .key('CompactSubButton' + this.timeStamp.toString())
1172              .onKeyEvent((event: KeyEvent) => {
1173                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH
1174                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1175                  this.resetFocusButton();
1176                  event.stopPropagation();
1177                }
1178                if (event.type === KeyType.Down &&
1179                  event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1180                  event.stopPropagation();
1181                  this.homeFirstValue();
1182                  this.focusWithTarget('CompactAddButton' + this.timeStamp.toString());
1183                }
1184                if (event.type === KeyType.Down &&
1185                  event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1186                  event.stopPropagation();
1187                  this.endLastValue();
1188                  if (this.addBtnStateEffect) {
1189                    this.addBtnStateEffect = false;
1190                    this.addOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
1191                    this.addBtnEnabled = false;
1192                  }
1193                  this.focusWithTarget('CompactSubButton' + this.timeStamp.toString());
1194                }
1195              })
1196              .onClick((event: ClickEvent) => {
1197                this.subValue();
1198                this.onChange?.(this.value);
1199                if (event.source === SourceType.Mouse ||
1200                  event.source === SourceType.TouchScreen) {
1201                  this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1202                }
1203              })
1204              .gesture(
1205                LongPressGesture({ repeat: true })
1206                  .onAction((event: GestureEvent) => {
1207                    if (event.repeat) {
1208                      this.subValue();
1209                      this.onChange?.(this.value);
1210                    }
1211                    if (event.source === SourceType.Mouse ||
1212                      event.source === SourceType.TouchScreen) {
1213                      this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1214                    }
1215                  })
1216              )
1217              .hoverEffect(this.choverEffect)
1218              .onHover((isHover: boolean) => {
1219                this.onHoverDecrease && this.onHoverDecrease(isHover);
1220              })
1221              .focusable(this.focusEnable)
1222              .groupDefaultFocus(true)
1223              .onFocus(() => {
1224                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1225                this.onFocusDecrease && this.onFocusDecrease();
1226                this.updateButtonStatus();
1227              })
1228              .onBlur(() => {
1229                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1230                this.onBlurDecrease && this.onBlurDecrease();
1231              })
1232          }
1233          .width(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1234          .height(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1235          .borderRadius(CounterResource.COUNTER_COMPACT_BUTTON_RADIUS)
1236          .borderWidth(this.subBtnFocusWidh)
1237          .borderColor(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1238          .margin({ start: LengthMetrics.vp(1) })
1239          .clip(true)
1240
1241          if (this.hasTextWidth) {
1242            Text(this.value.toString())
1243              .textAlign(TextAlign.Center)
1244              .fontSize(CounterResource.COUNTER_NUMBER_SIZE)
1245              .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
1246              .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1247              .width(this.textWidth.toString())
1248              .margin({
1249                start: LengthMetrics.vp(CounterResource.COUNTER_COMPACT_BUTTON_TEXT_MARGIN),
1250                end: LengthMetrics.vp(CounterResource.COUNTER_COMPACT_BUTTON_TEXT_MARGIN)
1251              })
1252          } else {
1253            Text(this.value.toString())
1254              .direction(this.counterDirection)
1255              .textAlign(TextAlign.Center)
1256              .fontSize(CounterResource.COUNTER_NUMBER_SIZE)
1257              .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
1258              .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1259              .margin({
1260                start: LengthMetrics.vp(CounterResource.COUNTER_COMPACT_BUTTON_TEXT_MARGIN),
1261                end: LengthMetrics.vp(CounterResource.COUNTER_COMPACT_BUTTON_TEXT_MARGIN)
1262              })
1263          }
1264
1265          Stack() {
1266            Image(CounterResource.BUTTON_ADD_ICON)
1267              .direction(this.counterDirection)
1268              .width(CounterResource.COUNTER_COMPACT_BUTTON_ICON_SIZE)
1269              .height(CounterResource.COUNTER_COMPACT_BUTTON_ICON_SIZE)
1270              .fillColor(CounterResource.BUTTON_ICON_COLOR)
1271              .opacity(this.addOpacity)
1272            Button({ type: ButtonType.Circle, stateEffect: this.addBtnStateEffect })
1273              .direction(this.counterDirection)
1274              .width(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1275              .height(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1276              .backgroundColor(CounterResource.BUTTON_BACKGROUD_COLOR)
1277              .opacity(this.addOpacity)
1278              .enabled(this.addBtnEnabled)
1279              .key('CompactAddButton' + this.timeStamp.toString())
1280              .onKeyEvent((event: KeyEvent) => {
1281                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH
1282                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1283                  this.resetFocusButton();
1284                  event.stopPropagation();
1285                }
1286                if (event.type === KeyType.Down &&
1287                  event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1288                  event.stopPropagation();
1289                  this.homeFirstValue();
1290                  if (this.subBtnStateEffect) {
1291                    this.subBtnStateEffect = false;
1292                    this.subOpacity = CounterResource.COUNTER_BUTTON_DISABLE_OPACITY;
1293                    this.subBtnEnabled = false;
1294                  }
1295                  this.focusWithTarget('CompactAddButton' + this.timeStamp.toString());
1296                }
1297                if (event.type === KeyType.Down &&
1298                  event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1299                  event.stopPropagation();
1300                  this.endLastValue();
1301                  this.focusWithTarget('CompactSubButton' + this.timeStamp.toString());
1302                }
1303              })
1304              .onClick((event: ClickEvent) => {
1305                this.addValue();
1306                this.onChange?.(this.value);
1307                if (event.source === SourceType.Mouse ||
1308                  event.source === SourceType.TouchScreen) {
1309                  this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1310                }
1311              })
1312              .gesture(
1313                LongPressGesture({ repeat: true })
1314                  .onAction((event: GestureEvent) => {
1315                    if (event.repeat) {
1316                      this.addValue();
1317                      this.onChange?.(this.value);
1318                    }
1319                    if (event.source === SourceType.Mouse ||
1320                      event.source === SourceType.TouchScreen) {
1321                      this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1322                    }
1323                  })
1324              )
1325              .hoverEffect(this.choverEffect)
1326              .onHover((isHover: boolean) => {
1327                this.onHoverIncrease && this.onHoverIncrease(isHover);
1328              })
1329              .focusable(this.focusEnable)
1330              .onFocus(() => {
1331                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1332                this.onFocusIncrease && this.onFocusIncrease();
1333                this.updateButtonStatus();
1334              })
1335              .onBlur(() => {
1336                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1337                this.onBlurIncrease && this.onBlurIncrease();
1338              })
1339          }
1340          .direction(this.counterDirection)
1341          .width(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1342          .height(CounterResource.COUNTER_COMPACT_BUTTON_SIZE)
1343          .borderRadius(CounterResource.COUNTER_COMPACT_BUTTON_RADIUS)
1344          .borderWidth(this.addBtnFocusWidh)
1345          .borderColor(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1346          .margin({ end: LengthMetrics.vp(1) })
1347          .clip(true)
1348        }
1349        .direction(this.counterDirection)
1350        .tabIndex(0)
1351        .height(CounterResource.COUNTER_COMPACT_CONTAINER_HEIGHT)
1352        .align(Alignment.Center)
1353        .borderWidth(CounterResource.COUNTER_BORDER_WIDTH)
1354        .borderColor(CounterResource.COUNTER_BORDER_COLOR)
1355        .borderRadius(CounterResource.COUNTER_COMPACT_CONTAINER_RADIUS)
1356
1357        Text(this.numberStyleOptions.label)
1358          .direction(this.counterDirection)
1359          .margin({ top: CounterResource.COUNTER_COMPACT_CONTAINER_LABEL_DISTANCE })
1360          .fontSize(CounterResource.COUNTER_COMPACT_LABEL_SIZE)
1361          .maxFontScale(CounterResource.COUNTER_LABEL_MAX_FONT_SIZE_SCALE);
1362          .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1363          .align(Alignment.Top)
1364      }
1365    } else if (this.type === CounterType.INLINE) {
1366      Row() {
1367        if (this.hasTextWidth) {
1368          RelativeContainer() {
1369            TextInput({
1370              text: this.hasInputText1 ? this.inputValue : this.value.toString(),
1371              controller: this.controller1
1372            })
1373              .alignRules({
1374                center: { anchor: '__container__', align: VerticalAlign.Center },
1375                middle: { anchor: '__container__', align: HorizontalAlign.Center }
1376              })
1377              .width(Math.min(this.getValueLength() * 9.6, this.textWidth))
1378              .height('20vp')
1379              .padding(0)
1380              .borderRadius(0)
1381              .textAlign(TextAlign.Center)
1382              .type(InputType.PhoneNumber)
1383              .caretColor(Color.Transparent)
1384              .copyOption(CopyOptions.None)
1385              .fontSize(this.getTextInputFontSize())
1386              .fontWeight(FontWeight.Medium)
1387              .fontColor(this.hasFocusText1 ? Color.White : CounterResource.COUNTER_TEXT_COLOR)
1388              .maxLength(this.getMaxLength())
1389              .backgroundColor(this.hasFocusText1 ? CounterResource.BUTTON_BORDER_FOCUSED_COLOR : Color.Transparent)
1390              .key('InlineTextInput' + this.timeStamp.toString())
1391              .onKeyEvent((event: KeyEvent) => {
1392                this.focusCurrentText(FocusText.TEXT1)
1393                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1394                  this.resetFocusText();
1395                  event.stopPropagation();
1396                }
1397                if (event.type === KeyType.Down &&
1398                  event.keyCode === CounterConstant.KEYCODE_DPAD_UP) {
1399                  this.addValue();
1400                  event.stopPropagation();
1401                }
1402                if (event.type === KeyType.Down &&
1403                  event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1404                  event.stopPropagation();
1405                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1406                }
1407                if (event.type === KeyType.Down &&
1408                  event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1409                  event.stopPropagation();
1410                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1411                }
1412                if (event.type === KeyType.Down &&
1413                  event.keyCode === CounterConstant.KEYCODE_DPAD_DOWN) {
1414                  this.subValue();
1415                  event.stopPropagation();
1416                }
1417                if (event.type === KeyType.Down &&
1418                  event.keyCode === CounterConstant.KEYCODE_DPAD_LEFT) {
1419                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1420                  event.stopPropagation();
1421                }
1422                if (event.type === KeyType.Down &&
1423                  event.keyCode === CounterConstant.KEYCODE_DPAD_RIGHT) {
1424                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1425                  event.stopPropagation();
1426                }
1427              })
1428              .onChange((value: string) => {
1429                this.inputValue = value;
1430                for (let i = 0; i < value.length; i++) {
1431                  let c = value[i];
1432                  if (c === '+' || c === '*' || c === '#') {
1433                    this.value -= 1;
1434                    this.value += 1;
1435                    this.inputValue = this.value.toString();
1436                    return;
1437                  }
1438                  if (c === '-' && i !== 0) {
1439                    this.inputValue = c;
1440                    break;
1441                  }
1442                }
1443
1444                this.hasInputText1 = true;
1445                let c = value[value.length - 1];
1446                if (value.length === this.getMaxLength()) {
1447                  this.inputValue = c;
1448                }
1449                if (this.timeoutID1 !== -1) {
1450                  clearTimeout(this.timeoutID1);
1451                  this.timeoutID1 = -1;
1452                }
1453                if (this.inputValue !== '' && Number(this.inputValue) <= this.max &&
1454                  Number(this.inputValue) >= this.min) {
1455                  this.value = Number(this.inputValue);
1456                  this.onChange?.(this.value);
1457                  this.hasInputText1 = false;
1458                } else {
1459                  if (Number(this.inputValue) > this.max ||
1460                    (Number(this.inputValue) < this.min &&
1461                      this.inputValue.length <= this.min.toString().length)) {
1462                    this.inputValue = c;
1463                  }
1464                  if (value.length < this.getMaxLength()) {
1465                    this.timeoutID1 = setTimeout(() => {
1466                      if (this.inputValue !== '' && Number(this.inputValue) <= this.max &&
1467                        Number(this.inputValue) >= this.min) {
1468                        this.value = Number(this.inputValue);
1469                        this.onChange?.(this.value);
1470                      }
1471                      this.inputValue = this.value.toString();
1472                      this.hasInputText1 = false;
1473                      this.updateInlineEnableSate();
1474                    }, 1500);
1475                  }
1476                }
1477                this.updateInlineEnableSate();
1478              })
1479              .onSubmit((enterKey: EnterKeyType) => {
1480                if (this.timeoutID1 != -1) {
1481                  clearTimeout(this.timeoutID1);
1482                  this.timeoutID1 = -1;
1483                }
1484                this.hasInputText1 = false;
1485                this.value -= 1;
1486                if (Number(this.inputValue) >= this.min && Number(this.inputValue) <= this.max) {
1487                  this.value = Number(this.inputValue);
1488                  this.onChange?.(this.value);
1489                  this.updateInlineEnableSate();
1490                } else {
1491                  this.value += 1;
1492                  this.inputValue = this.value.toString();
1493                }
1494              })
1495              .focusable(true)
1496              .focusOnTouch(true)
1497              .onFocus(() => {
1498                this.focusText = FocusText.TEXT1;
1499                this.hasFocusText1 = true;
1500                this.controller1.caretPosition(this.value.toString().length);
1501              })
1502              .onBlur(() => {
1503                this.focusText = FocusText.NONE;
1504                this.hasFocusText1 = false;
1505              })
1506              .onClick((event: ClickEvent) => {
1507                this.focusText = FocusText.TEXT1;
1508                this.hasFocusText1 = true;
1509                this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1510                this.controller1.caretPosition(this.value.toString().length);
1511              })
1512          }
1513          .direction(this.counterDirection)
1514          .margin({
1515            start: LengthMetrics.vp(CounterResource.COUNTER_INLINE_INPUT_TEXT_MARGIN),
1516            end: LengthMetrics.vp(CounterResource.COUNTER_INLINE_INPUT_TEXT_MARGIN)
1517          })
1518          .height('100%')
1519          .width(this.textWidth)
1520        } else {
1521          Row() {
1522            TextInput({
1523              text: this.hasInputText1 ? this.inputValue : this.value.toString(),
1524              controller: this.controller1
1525            })
1526              .direction(this.counterDirection)
1527              .width(this.getValueLength() * 9.6)
1528              .height('20vp')
1529              .padding(0)
1530              .borderRadius(0)
1531              .textAlign(TextAlign.Center)
1532              .type(InputType.PhoneNumber)
1533              .caretColor(Color.Transparent)
1534              .copyOption(CopyOptions.None)
1535              .fontSize(this.getTextInputFontSize())
1536              .fontWeight(FontWeight.Medium)
1537              .fontColor(this.hasFocusText1 ? Color.White : CounterResource.COUNTER_TEXT_COLOR)
1538              .maxLength(this.getMaxLength())
1539              .backgroundColor(this.hasFocusText1 ? CounterResource.BUTTON_BORDER_FOCUSED_COLOR : Color.Transparent)
1540              .key('InlineTextInput' + this.timeStamp.toString())
1541              .onKeyEvent((event: KeyEvent) => {
1542                this.focusCurrentText(FocusText.TEXT1)
1543                if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1544                  this.resetFocusText();
1545                  event.stopPropagation();
1546                }
1547                if (event.type === KeyType.Down &&
1548                  event.keyCode === CounterConstant.KEYCODE_DPAD_UP) {
1549                  this.addValue();
1550                  event.stopPropagation();
1551                }
1552                if (event.type === KeyType.Down &&
1553                  event.keyCode === CounterConstant.KEYCODE_DPAD_DOWN) {
1554                  this.subValue();
1555                  event.stopPropagation();
1556                }
1557                if (event.type === KeyType.Down &&
1558                  event.keyCode === CounterConstant.KEYCODE_DPAD_LEFT) {
1559                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1560                  event.stopPropagation();
1561                }
1562                if (event.type === KeyType.Down &&
1563                  event.keyCode === CounterConstant.KEYCODE_DPAD_RIGHT) {
1564                  this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1565                  event.stopPropagation();
1566                }
1567              })
1568              .onChange((value: string) => {
1569                this.inputValue = value;
1570                for (let i = 0; i < value.length; i++) {
1571                  let c = value[i];
1572                  if (c === '+' || c === '*' || c === '#') {
1573                    this.value -= 1;
1574                    this.value += 1;
1575                    this.inputValue = this.value.toString();
1576                    return;
1577                  }
1578                  if (c === '-' && i !== 0) {
1579                    this.inputValue = c;
1580                    break;
1581                  }
1582                }
1583
1584                this.hasInputText1 = true;
1585                let c = value[value.length -1];
1586                if (value.length === this.getMaxLength()) {
1587                  this.inputValue = c;
1588                }
1589                if (this.timeoutID1 !== -1) {
1590                  clearTimeout(this.timeoutID1);
1591                  this.timeoutID1 = -1;
1592                }
1593                if (this.inputValue !== '' && Number(this.inputValue) <= this.max &&
1594                  Number(this.inputValue) >= this.min) {
1595                  this.value = Number(this.inputValue);
1596                  this.onChange?.(this.value);
1597                  this.hasInputText1 = false;
1598                } else {
1599                  if (Number(this.inputValue) > this.max ||
1600                    (Number(this.inputValue) < this.min &&
1601                      this.inputValue.length <= this.min.toString().length)) {
1602                    this.inputValue = c;
1603                  }
1604                  if (value.length < this.getMaxLength()) {
1605                    this.timeoutID1 = setTimeout(() => {
1606                      if (this.inputValue !== '' && Number(this.inputValue) <= this.max &&
1607                        Number(this.inputValue) >= this.min) {
1608                        this.value = Number(this.inputValue);
1609                        this.onChange?.(this.value);
1610                      }
1611                      this.inputValue = this.value.toString()
1612                      this.hasInputText1 = false;
1613                      this.updateInlineEnableSate();
1614                    }, 1500);
1615                  }
1616                }
1617                this.updateInlineEnableSate();
1618              })
1619              .onSubmit((enterKey: EnterKeyType) => {
1620                if (this.timeoutID1 !== -1) {
1621                  clearTimeout(this.timeoutID1);
1622                  this.timeoutID1 = -1;
1623                }
1624                this.hasInputText1 = false;
1625                this.value -= 1;
1626                if (Number(this.inputValue) >= this.min && Number(this.inputValue) <= this.max) {
1627                  this.value = Number(this.inputValue);
1628                  this.onChange?.(this.value);
1629                  this.updateInlineEnableSate();
1630                } else {
1631                  this.value += 1;
1632                  this.inputValue = this.value.toString();
1633                }
1634              })
1635              .focusable(true)
1636              .focusOnTouch(true)
1637              .onFocus(() => {
1638                this.focusText = FocusText.TEXT1;
1639                this.hasFocusText1 = true;
1640                this.controller1.caretPosition(this.value.toString().length);
1641              })
1642              .onBlur(() => {
1643                this.focusText = FocusText.NONE;
1644                this.hasFocusText1 = false;
1645              })
1646              .onClick((event: ClickEvent) => {
1647                this.focusText = FocusText.TEXT1;
1648                this.hasFocusText1 = true;
1649                this.focusWithTarget('InlineTextInput' + this.timeStamp.toString());
1650                this.controller1.caretPosition(this.value.toString().length);
1651              })
1652          }
1653          .direction(this.counterDirection)
1654          .margin({
1655            start: LengthMetrics.vp(CounterResource.COUNTER_INLINE_INPUT_TEXT_MARGIN),
1656            end: LengthMetrics.vp(CounterResource.COUNTER_INLINE_INPUT_TEXT_MARGIN)
1657          })
1658        }
1659
1660        Column() {
1661          Stack() {
1662            Rect()
1663              .direction(this.counterDirection)
1664              .width(CounterResource.COUNTER_INLINE_FOCUS_BORDER_WIDTH)
1665              .height(CounterResource.COUNTER_INLINE_FOCUS_BORDER_HEIGHT)
1666              .radius([
1667                ['0vp', '0vp'],
1668                [CounterResource.COUNTER_INLINE_RADIUS, CounterResource.COUNTER_INLINE_RADIUS],
1669                ['0vp', '0vp'],
1670                ['0vp', '0vp']])
1671              .strokeWidth(this.addBtnFocusWidh)
1672              .stroke(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1673              .margin({ end: LengthMetrics.vp(2) })
1674              .fillOpacity(0)
1675            Image(CounterResource.BUTTON_ARROW_UP)
1676              .direction(this.counterDirection)
1677              .width(CounterResource.COUNTER_INLINE_BUTTON_ICON_WIDTH)
1678              .height(CounterResource.COUNTER_INLINE_BUTTON_ICON_HEIGHT)
1679              .fillColor(CounterResource.BUTTON_ICON_COLOR)
1680              .opacity(this.addOpacity)
1681
1682            Button({ type: ButtonType.Normal, stateEffect: this.addBtnStateEffect })
1683              .direction(this.counterDirection)
1684              .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
1685              .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
1686              .backgroundColor(Color.Transparent)
1687              .opacity(this.addOpacity)
1688              .enabled(this.addBtnEnabled)
1689              .onClick((event: ClickEvent) => {
1690                this.addValue();
1691                if (event.source === SourceType.Mouse ||
1692                  event.source === SourceType.TouchScreen) {
1693                  this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1694                }
1695              })
1696              .gesture(
1697                LongPressGesture({ repeat: true })
1698                  .onAction((event: GestureEvent) => {
1699                    if (event.repeat) {
1700                      this.addValue();
1701                    }
1702                    this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1703                  })
1704              )
1705              .hoverEffect(this.choverEffect)
1706              .onHover((isHover: boolean) => {
1707                this.onHoverIncrease && this.onHoverIncrease(isHover);
1708              })
1709              .focusable(false)
1710              .onFocus(() => {
1711                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1712                this.onFocusIncrease && this.onFocusIncrease();
1713              })
1714              .onBlur(() => {
1715                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1716                this.onBlurIncrease && this.onBlurIncrease();
1717              })
1718          }
1719          .direction(this.counterDirection)
1720          .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
1721          .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
1722          .padding({ top: '1vp' })
1723          .borderWidth({ bottom: '1vp' })
1724          .borderColor(CounterResource.COUNTER_BORDER_COLOR)
1725          .clip(true)
1726
1727          Stack() {
1728            Rect()
1729              .direction(this.counterDirection)
1730              .width(CounterResource.COUNTER_INLINE_FOCUS_BORDER_WIDTH)
1731              .height(CounterResource.COUNTER_INLINE_FOCUS_BORDER_HEIGHT)
1732              .radius([
1733                ['0vp', '0vp'],
1734                ['0vp', '0vp'],
1735                [CounterResource.COUNTER_INLINE_RADIUS, CounterResource.COUNTER_INLINE_RADIUS],
1736                ['0vp', '0vp']
1737              ])
1738              .strokeWidth(this.subBtnFocusWidh)
1739              .stroke(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
1740              .margin({ top: LengthMetrics.vp(1), end: LengthMetrics.vp(1), bottom: LengthMetrics.vp(2) })
1741              .fillOpacity(0)
1742            Image(CounterResource.BUTTON_ARROW_DOWN)
1743              .direction(this.counterDirection)
1744              .width(CounterResource.COUNTER_INLINE_BUTTON_ICON_WIDTH)
1745              .height(CounterResource.COUNTER_INLINE_BUTTON_ICON_HEIGHT)
1746              .fillColor(CounterResource.BUTTON_ICON_COLOR)
1747              .opacity(this.subOpacity)
1748            Button({ type: ButtonType.Normal, stateEffect: this.subBtnStateEffect })
1749              .direction(this.counterDirection)
1750              .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
1751              .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
1752              .backgroundColor(Color.Transparent)
1753              .opacity(this.subOpacity)
1754              .enabled(this.subBtnEnabled)
1755              .onClick((event: ClickEvent) => {
1756                this.subValue();
1757                if (event.source === SourceType.Mouse ||
1758                  event.source === SourceType.TouchScreen) {
1759                  this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1760                }
1761              })
1762              .gesture(
1763                LongPressGesture({ repeat: true })
1764                  .onAction((event: GestureEvent) => {
1765                    if (event.repeat) {
1766                      this.subValue();
1767                    }
1768                    this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1769                  })
1770              )
1771              .hoverEffect(this.choverEffect)
1772              .onHover((isHover: boolean) => {
1773                this.onHoverDecrease && this.onHoverDecrease(isHover);
1774              })
1775              .focusable(false)
1776              .onFocus(() => {
1777                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
1778                this.onFocusDecrease && this.onFocusDecrease();
1779              })
1780              .onBlur(() => {
1781                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
1782                this.onBlurDecrease && this.onBlurDecrease();
1783              })
1784          }
1785          .direction(this.counterDirection)
1786          .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
1787          .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
1788          .clip(true)
1789        }
1790        .direction(this.counterDirection)
1791        .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
1792        .height(CounterResource.COUNTER_INLINE_CONTAINER_HEIGHT)
1793        .borderWidth({ start: LengthMetrics.vp(CounterResource.COUNTER_BORDER_WIDTH_NUMBER) })
1794        .borderColor(CounterResource.COUNTER_BORDER_COLOR)
1795      }
1796      .direction(this.counterDirection)
1797      .height(CounterResource.COUNTER_INLINE_CONTAINER_HEIGHT)
1798      .borderWidth(CounterResource.COUNTER_BORDER_WIDTH)
1799      .borderColor(CounterResource.COUNTER_BORDER_COLOR)
1800      .borderRadius(CounterResource.COUNTER_INLINE_RADIUS)
1801      .clip(true)
1802    } else if (this.type === CounterType.INLINE_DATE) {
1803      Row() {
1804        Row() {
1805          TextInput({
1806            text: this.hasInputText1 ? this.inputYear.toString() : this.getYear(),
1807            controller: this.controller1
1808          })
1809            .direction(this.counterDirection)
1810            .type(InputType.Number)
1811            .caretColor(Color.Transparent)
1812            .copyOption(CopyOptions.None)
1813            .fontSize(this.getTextInputFontSize())
1814            .fontWeight(FontWeight.Medium)
1815            .fontColor(this.hasFocusText1 ? Color.White : CounterResource.COUNTER_TEXT_COLOR)
1816            .maxLength(5)
1817            .padding(0)
1818            .backgroundColor(this.hasFocusText1 ? CounterResource.BUTTON_BORDER_FOCUSED_COLOR : Color.Transparent)
1819            .width('38vp')
1820            .height('20vp')
1821            .borderRadius(0)
1822            .borderWidth(0)
1823            .key('DateTextInput1' + this.timeStamp.toString())
1824            .onKeyEvent((event: KeyEvent) => {
1825              this.focusCurrentText(FocusText.TEXT1);
1826              if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1827                this.resetFocusText();
1828                event.stopPropagation();
1829              }
1830              if (event.type === KeyType.Down &&
1831                event.keyCode === CounterConstant.KEYCODE_DPAD_UP) {
1832                this.addDate();
1833                event.stopPropagation();
1834              }
1835              if (event.type === KeyType.Down &&
1836                event.keyCode === CounterConstant.KEYCODE_DPAD_DOWN) {
1837                this.subDate();
1838                event.stopPropagation();
1839              }
1840              if (event.type === KeyType.Down &&
1841                event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1842                this.homeFocusText();
1843                event.stopPropagation();
1844              }
1845              if (event.type === KeyType.Down &&
1846                event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1847                this.endFocusText();
1848                event.stopPropagation();
1849              }
1850              if (event.type === KeyType.Down &&
1851                event.keyCode === CounterConstant.KEYCODE_DPAD_LEFT) {
1852                this.focusWithTarget('DateTextInput1' + this.timeStamp.toString());
1853                event.stopPropagation();
1854              }
1855              if (event.type === KeyType.Down &&
1856                event.keyCode === CounterConstant.KEYCODE_DPAD_RIGHT) {
1857                this.focusWithTarget('DateTextInput2' + this.timeStamp.toString());
1858              }
1859            })
1860            .onChange((value: string) => {
1861              if (value.length !== 4) {
1862                this.hasInputText1 = true;
1863              }
1864              this.inputYear = Number(value)
1865              if (value.length === 5) {
1866                this.inputYear = this.inputYear % 10;
1867              }
1868
1869              if (this.timeoutID1 !== -1) {
1870                clearTimeout(this.timeoutID1);
1871                this.timeoutID1 = -1;
1872              }
1873
1874              this.timeoutID1 = setTimeout(() => {
1875                this.hasInputText1 = false;
1876                this.inputYear = this.year;
1877                this.updateDateEnableSate();
1878                this.updateDay();
1879              }, 1500);
1880
1881              if (this.inputYear >= this.minYear && this.inputYear <= this.maxYear) {
1882                this.year = this.inputYear;
1883                this.updateDateEnableSate();
1884                this.updateDay();
1885              }
1886
1887              if (value.length === 4) {
1888                let date = new DateData(this.year, this.month, this.day);
1889                this.onDateChange?.(date);
1890              }
1891            })
1892            .onSubmit((enterKey: EnterKeyType) => {
1893              if (this.timeoutID1 !== -1) {
1894                clearTimeout(this.timeoutID1);
1895                this.timeoutID1 = -1;
1896              }
1897              this.hasInputText1 = false;
1898              this.year -= 1;
1899              if (this.inputYear >= this.minYear && this.inputYear <= this.maxYear) {
1900                this.year = this.inputYear;
1901              } else {
1902                this.year += 1;
1903                this.inputYear = this.year;
1904              }
1905              this.updateDateEnableSate();
1906              this.updateDay();
1907            })
1908            .tabIndex(0)
1909            .focusOnTouch(true)
1910            .focusable(true)
1911            .onFocus(() => {
1912              this.focusText = FocusText.TEXT1;
1913              this.hasFocusText1 = true;
1914              this.updateDateEnableSate();
1915              this.controller1.caretPosition(this.getYear().length);
1916            })
1917            .onBlur(() => {
1918              this.focusText = FocusText.NONE;
1919              this.hasFocusText1 = false;
1920              this.updateDateEnableSate();
1921            })
1922            .onClick((event: ClickEvent) => {
1923              this.focusText = FocusText.TEXT1;
1924              this.hasFocusText1 = true;
1925              this.updateDateEnableSate();
1926              this.controller1.caretPosition(this.getYear().length);
1927            })
1928          Text('/')
1929            .direction(this.counterDirection)
1930            .textAlign(TextAlign.Center)
1931            .fontSize(CounterResource.COUNTER_NUMBER_SIZE)
1932            .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
1933            .fontColor(CounterResource.COUNTER_TEXT_COLOR)
1934            .width('8vp')
1935          TextInput({
1936            text: this.hasInputText2 ? this.inputMoon.toString() : this.convertNumberToString(this.month),
1937            controller: this.controller2
1938          })
1939            .direction(this.counterDirection)
1940            .type(InputType.Number)
1941            .caretColor(Color.Transparent)
1942            .copyOption(CopyOptions.None)
1943            .fontSize(this.getTextInputFontSize())
1944            .fontWeight(FontWeight.Medium)
1945            .fontColor(this.hasFocusText2 ? Color.White : CounterResource.COUNTER_TEXT_COLOR)
1946            .maxLength(3)
1947            .padding(0)
1948            .backgroundColor(this.hasFocusText2 ? CounterResource.BUTTON_BORDER_FOCUSED_COLOR : Color.Transparent)
1949            .width('19vp')
1950            .height('20vp')
1951            .borderRadius(0)
1952            .key('DateTextInput2' + this.timeStamp.toString())
1953            .onKeyEvent((event: KeyEvent) => {
1954              this.focusCurrentText(FocusText.TEXT2)
1955              if (event.keyCode === CounterConstant.KEYCODE_ESC) {
1956                this.resetFocusText();
1957                event.stopPropagation();
1958              }
1959              if (event.type === KeyType.Down &&
1960                event.keyCode === CounterConstant.KEYCODE_DPAD_DOWN) {
1961                this.subDate();
1962                this.updateDay();
1963                event.stopPropagation();
1964              }
1965              if (event.type === KeyType.Down &&
1966                event.keyCode === CounterConstant.KEYCODE_DPAD_UP) {
1967                this.addDate();
1968                this.updateDay();
1969                event.stopPropagation();
1970              }
1971              if (event.type === KeyType.Down &&
1972                event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
1973                this.homeFocusText();
1974                event.stopPropagation();
1975              }
1976              if (event.type === KeyType.Down &&
1977                event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
1978                this.endFocusText();
1979                event.stopPropagation();
1980              }
1981              if (event.type === KeyType.Down &&
1982                event.keyCode === CounterConstant.KEYCODE_DPAD_LEFT) {
1983                this.focusWithTarget('DateTextInput1' + this.timeStamp.toString());
1984              }
1985              if (event.type === KeyType.Down &&
1986                event.keyCode === CounterConstant.KEYCODE_DPAD_RIGHT) {
1987                this.focusWithTarget('DateTextInput3' + this.timeStamp.toString());
1988              }
1989
1990              if (event.type === KeyType.Down &&
1991                event.keyCode === CounterConstant.KEYCODE_TAB) {
1992                event.stopPropagation();
1993                this.focusWithTarget('DateTextInput1' + this.timeStamp.toString());
1994              }
1995            })
1996            .onChange((value: string) => {
1997              this.inputMoon = Number(value);
1998              if (value.length !== 2) {
1999                this.hasInputText2 = true;
2000              }
2001              if (value.length === 3) {
2002                this.inputMoon = this.inputMoon % 10;
2003              }
2004              if (this.timeoutID2 !== -1) {
2005                clearTimeout(this.timeoutID2);
2006                this.timeoutID2 = -1;
2007              }
2008
2009              this.timeoutID2 = setTimeout(() => {
2010                this.hasInputText2 = false;
2011                this.month -= 1;
2012                if (this.inputMoon >= 1 && this.inputMoon <= 12) {
2013                  this.month = this.inputMoon;
2014                } else {
2015                  this.month += 1;
2016                  this.inputMoon = this.month;
2017                }
2018                this.updateDay();
2019              }, 1000);
2020
2021              if (value.length === 2) {
2022                this.hasInputText2 = false;
2023                this.month -= 1;
2024                if (this.inputMoon >= 1 && this.inputMoon <= 12) {
2025                  this.month = this.inputMoon;
2026                  let date = new DateData(this.year, this.month, this.day);
2027                  this.onDateChange?.(date);
2028                } else {
2029                  this.month += 1;
2030                  this.inputMoon = this.month;
2031                }
2032                this.updateDay();
2033              }
2034            })
2035            .onSubmit((enterKey: EnterKeyType) => {
2036              if (this.timeoutID2 !== -1) {
2037                clearTimeout(this.timeoutID2);
2038                this.timeoutID2 = -1;
2039              }
2040              this.hasInputText2 = false;
2041              this.month -= 1;
2042              if (this.inputMoon >= 1 && this.inputMoon <= 12) {
2043                this.month = this.inputMoon;
2044                this.updateDay();
2045              } else {
2046                this.month += 1;
2047              }
2048            })
2049            .focusOnTouch(true)
2050            .tabIndex(-1)
2051            .focusable(true)
2052            .onFocus(() => {
2053              this.focusText = FocusText.TEXT2;
2054              this.hasFocusText2 = true;
2055              this.controller2.caretPosition(this.convertNumberToString(this.month).length);
2056            })
2057            .onBlur(() => {
2058              this.focusText = FocusText.NONE
2059              this.hasFocusText2 = false
2060            })
2061            .onClick((event: ClickEvent) => {
2062              this.focusText = FocusText.TEXT2;
2063              this.hasFocusText2 = true;
2064              this.controller2.caretPosition(this.convertNumberToString(this.month).length);
2065            })
2066          Text('/')
2067            .direction(this.counterDirection)
2068            .textAlign(TextAlign.Center)
2069            .fontSize(CounterResource.COUNTER_NUMBER_SIZE)
2070            .maxFontScale(CounterResource.COUNTER_NUMBER_MAX_FONT_SIZE_SCALE);
2071            .fontColor(CounterResource.COUNTER_TEXT_COLOR)
2072            .width('8vp')
2073          TextInput({
2074            text: this.hasInputText3 ? this.inputDay.toString() : this.convertNumberToString(this.day),
2075            controller: this.controller3
2076          })
2077            .direction(this.counterDirection)
2078            .type(InputType.Number)
2079            .caretColor(Color.Transparent)
2080            .copyOption(CopyOptions.None)
2081            .fontSize(this.getTextInputFontSize())
2082            .fontWeight(FontWeight.Medium)
2083            .fontColor(this.hasFocusText3 ? Color.White : CounterResource.COUNTER_TEXT_COLOR)
2084            .maxLength(3)
2085            .padding(0)
2086            .backgroundColor(this.hasFocusText3 ? CounterResource.BUTTON_BORDER_FOCUSED_COLOR : Color.Transparent)
2087            .width('19vp')
2088            .height('20vp')
2089            .borderRadius(0)
2090            .key('DateTextInput3' + this.timeStamp.toString())
2091            .onKeyEvent((event: KeyEvent) => {
2092              this.focusCurrentText(FocusText.TEXT3)
2093              if (event.keyCode === CounterConstant.KEYCODE_ESC) {
2094                this.resetFocusText();
2095                event.stopPropagation();
2096              }
2097              if (event.type === KeyType.Down &&
2098                event.keyCode === CounterConstant.KEYCODE_DPAD_DOWN) {
2099                this.subDate();
2100                event.stopPropagation();
2101              }
2102              if (event.type === KeyType.Down &&
2103                event.keyCode === CounterConstant.KEYCODE_DPAD_UP) {
2104                this.addDate();
2105                event.stopPropagation();
2106              }
2107              if (event.type === KeyType.Down &&
2108                event.keyCode === CounterConstant.KEYCODE_MOVE_HOME) {
2109                this.homeFocusText();
2110                event.stopPropagation();
2111              }
2112              if (event.type === KeyType.Down &&
2113                event.keyCode === CounterConstant.KEYCODE_MOVE_END) {
2114                this.endFocusText();
2115                event.stopPropagation();
2116              }
2117              if (event.type === KeyType.Down &&
2118                event.keyCode === CounterConstant.KEYCODE_DPAD_LEFT) {
2119                this.focusWithTarget('DateTextInput2' + this.timeStamp.toString());
2120              }
2121
2122              if (event.type === KeyType.Down &&
2123                event.keyCode === CounterConstant.KEYCODE_DPAD_RIGHT) {
2124                this.focusWithTarget('DateTextInput3' + this.timeStamp.toString());
2125                event.stopPropagation();
2126              }
2127
2128              if (event.type === KeyType.Down &&
2129                event.keyCode === CounterConstant.KEYCODE_TAB) {
2130                event.stopPropagation();
2131                this.focusWithTarget('DateTextInput1' + this.timeStamp.toString());
2132              }
2133            })
2134            .onChange((value: string) => {
2135              this.inputDay = Number(value)
2136              if (value.length !== 2) {
2137                this.hasInputText3 = true;
2138              }
2139              if (value.length === 3) {
2140                this.inputDay = this.inputDay % 10;
2141              }
2142              if (this.timeoutID3 !== -1) {
2143                clearTimeout(this.timeoutID3);
2144                this.timeoutID3 = -1;
2145              }
2146
2147              this.timeoutID3 = setTimeout(() => {
2148                this.hasInputText3 = false;
2149                this.day -= 1;
2150                if (this.inputDay >= 1 && this.inputDay <= this.getDayNumber()) {
2151                  this.day = this.inputDay;
2152                } else {
2153                  this.day += 1;
2154                  this.inputDay = this.day;
2155                }
2156              }, 1000);
2157
2158              if (value.length === 2) {
2159                this.hasInputText3 = false;
2160                this.day -= 1;
2161                if (this.inputDay >= 1 && this.inputDay <= this.getDayNumber()) {
2162                  this.day = this.inputDay;
2163                  let date = new DateData(this.year, this.month, this.day);
2164                  this.onDateChange?.(date);
2165                } else {
2166                  this.day += 1;
2167                  this.inputDay = this.day;
2168                }
2169              }
2170            })
2171            .onSubmit((enterKey: EnterKeyType) => {
2172              if (this.timeoutID3 !== -1) {
2173                clearTimeout(this.timeoutID3);
2174                this.timeoutID3 = -1;
2175              }
2176              this.hasInputText3 = false;
2177              this.day -= 1;
2178              if (this.inputDay >= 1 && this.inputDay <= this.getDayNumber()) {
2179                this.day = this.inputDay;
2180              } else {
2181                this.day += 1;
2182              }
2183            })
2184            .tabIndex(-2)
2185            .focusOnTouch(true)
2186            .focusable(true)
2187            .onFocus(() => {
2188              this.focusText = FocusText.TEXT3;
2189              this.hasFocusText3 = true;
2190              this.controller3.caretPosition(this.convertNumberToString(this.day).length);
2191            })
2192            .onBlur(() => {
2193              this.focusText = FocusText.NONE;
2194              this.hasFocusText3 = false;
2195            })
2196            .onClick((event: ClickEvent) => {
2197              this.focusText = FocusText.TEXT3;
2198              this.hasFocusText3 = true;
2199              this.controller3.caretPosition(this.convertNumberToString(this.day).length);
2200            })
2201        }
2202        .direction(this.counterDirection)
2203        .width('92vp')
2204        .height(CounterResource.COUNTER_INLINE_CONTAINER_HEIGHT)
2205        .margin({
2206          start: LengthMetrics.vp(CounterResource.COUNTER_INLINE_DATE_TEXT_MARGIN),
2207          end: LengthMetrics.vp(CounterResource.COUNTER_INLINE_DATE_TEXT_MARGIN)
2208        })
2209
2210        Column() {
2211          Stack() {
2212            Rect()
2213              .direction(this.counterDirection)
2214              .width(CounterResource.COUNTER_INLINE_FOCUS_BORDER_WIDTH)
2215              .height(CounterResource.COUNTER_INLINE_FOCUS_BORDER_HEIGHT)
2216              .radius([
2217                ['0vp', '0vp'],
2218                [CounterResource.COUNTER_INLINE_RADIUS, CounterResource.COUNTER_INLINE_RADIUS],
2219                ['0vp', '0vp'],
2220                ['0vp', '0vp']])
2221              .strokeWidth(this.addBtnFocusWidh)
2222              .stroke(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
2223              .margin({ end: LengthMetrics.vp(1) })
2224              .fillOpacity(0)
2225            Image(CounterResource.BUTTON_ARROW_UP)
2226              .direction(this.counterDirection)
2227              .width(CounterResource.COUNTER_INLINE_BUTTON_ICON_WIDTH)
2228              .height(CounterResource.COUNTER_INLINE_BUTTON_ICON_HEIGHT)
2229              .fillColor(CounterResource.BUTTON_ICON_COLOR)
2230              .opacity(this.addOpacity)
2231            Button({ type: ButtonType.Normal, stateEffect: this.addBtnStateEffect })
2232              .direction(this.counterDirection)
2233              .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
2234              .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
2235              .backgroundColor(Color.Transparent)
2236              .opacity(this.addOpacity)
2237              .enabled(this.addBtnEnabled)
2238              .onClick((event: ClickEvent) => {
2239                this.addDate();
2240                if (event.source === SourceType.Mouse ||
2241                  event.source === SourceType.TouchScreen) {
2242                  this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2243                }
2244              })
2245              .gesture(
2246                LongPressGesture({ repeat: true })
2247                  .onAction((event: GestureEvent) => {
2248                    if (event.repeat) {
2249                      this.addDate();
2250                    }
2251                    this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2252                  })
2253              )
2254              .hoverEffect(this.choverEffect)
2255              .onHover((isHover: boolean) => {
2256                this.onHoverIncrease && this.onHoverIncrease(isHover);
2257              })
2258              .focusable(false)
2259              .onFocus(() => {
2260                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
2261                this.onFocusIncrease && this.onFocusIncrease();
2262              })
2263              .onBlur(() => {
2264                this.addBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2265                this.onBlurIncrease && this.onBlurIncrease();
2266              })
2267          }
2268          .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
2269          .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
2270          .padding({ top: '1vp' })
2271          .borderWidth({ bottom: '1vp' })
2272          .borderColor(CounterResource.COUNTER_BORDER_COLOR)
2273          .clip(true)
2274
2275          Stack() {
2276            Rect()
2277              .direction(this.counterDirection)
2278              .width(CounterResource.COUNTER_INLINE_FOCUS_BORDER_WIDTH)
2279              .height(CounterResource.COUNTER_INLINE_FOCUS_BORDER_HEIGHT)
2280              .radius([
2281                ['0vp', '0vp'],
2282                ['0vp', '0vp'],
2283                [CounterResource.COUNTER_INLINE_RADIUS, CounterResource.COUNTER_INLINE_RADIUS],
2284                ['0vp', '0vp']
2285              ])
2286              .strokeWidth(this.subBtnFocusWidh)
2287              .stroke(CounterResource.BUTTON_BORDER_FOCUSED_COLOR)
2288              .margin({ top: LengthMetrics.vp(1), end: LengthMetrics.vp(1), bottom: LengthMetrics.vp(2) })
2289              .fillOpacity(0)
2290            Image(CounterResource.BUTTON_ARROW_DOWN)
2291              .direction(this.counterDirection)
2292              .width(CounterResource.COUNTER_INLINE_BUTTON_ICON_WIDTH)
2293              .height(CounterResource.COUNTER_INLINE_BUTTON_ICON_HEIGHT)
2294              .fillColor(CounterResource.BUTTON_ICON_COLOR)
2295              .opacity(this.subOpacity)
2296            Button({ type: ButtonType.Normal, stateEffect: this.subBtnStateEffect })
2297              .direction(this.counterDirection)
2298              .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
2299              .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
2300              .backgroundColor(Color.Transparent)
2301              .opacity(this.subOpacity)
2302              .enabled(this.subBtnEnabled)
2303              .onClick((event: ClickEvent) => {
2304                this.subDate();
2305                if (event.source === SourceType.Mouse ||
2306                  event.source === SourceType.TouchScreen) {
2307                  this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2308                }
2309              })
2310              .gesture(
2311                LongPressGesture({ repeat: true })
2312                  .onAction((event: GestureEvent) => {
2313                    if (event.repeat) {
2314                      this.subDate();
2315                    }
2316                    this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2317                  })
2318              )
2319              .hoverEffect(this.choverEffect)
2320              .onHover((isHover: boolean) => {
2321                this.onHoverDecrease && this.onHoverDecrease(isHover);
2322              })
2323              .focusable(false)
2324              .onFocus(() => {
2325                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_FOCUSED_WIDTH;
2326                this.onFocusDecrease && this.onFocusDecrease();
2327              })
2328              .onBlur(() => {
2329                this.subBtnFocusWidh = CounterResource.BUTTON_BORDER_BLUR_WIDTH;
2330                this.onBlurDecrease && this.onBlurDecrease();
2331              })
2332          }.width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
2333          .height(CounterResource.COUNTER_INLINE_BUTTON_HEIGHT)
2334          .clip(true)
2335        }
2336        .direction(this.counterDirection)
2337        .width(CounterResource.COUNTER_INLINE_BUTTON_WIDTH)
2338        .height(CounterResource.COUNTER_INLINE_CONTAINER_HEIGHT)
2339        .borderWidth({ start: LengthMetrics.vp(CounterResource.COUNTER_BORDER_WIDTH_NUMBER) })
2340        .borderColor(CounterResource.COUNTER_BORDER_COLOR)
2341      }
2342      .direction(this.counterDirection)
2343      .height(CounterResource.COUNTER_INLINE_CONTAINER_HEIGHT)
2344      .borderWidth(CounterResource.COUNTER_BORDER_WIDTH)
2345      .borderColor(CounterResource.COUNTER_BORDER_COLOR)
2346      .borderRadius(CounterResource.COUNTER_INLINE_RADIUS)
2347      .clip(true)
2348    } else {
2349
2350    }
2351  }
2352}
2353