1/*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16const SPACE_MARGIN: number = 8
17const MARGIN_NUM: number = 4
18const IMAGE_WIDTH_NUM: number = 16
19const IMAGE_HEIGHT_NUM: number = 24
20const BUTTON_SIZE: number = 32
21const SINGLE_LINE_HEIGHT: number = 48
22const DOUBLE_LINE_HEIGHT: number = 64
23const BUTTON_HEIGHT: number = 28
24const IMAGE_WIDTH: number = 12
25const BORDER_WIDTH = 2
26const DIVIDEND_WIDTH = 3
27const SINGLE_LINE_NUM: number = 1
28const DOUBLE_LINE_NUM: number = 2
29const MIN_FONT_SIZE: number = 14
30const MAIN_TEXT_SIZE: number = 10
31const CONSTRAINT_WIDTH: number = 40
32const CONSTRAINT_NUM: number = 44
33
34export enum OperationType {
35  TEXT_ARROW = 0,
36  BUTTON = 1,
37  ICON_GROUP = 2,
38  LOADING = 3,
39}
40
41export declare type OperationOption = {
42  value: ResourceStr;
43  action?: () => void;
44}
45
46export declare type SelectOptions = {
47  options: Array<SelectOption>;
48  selected?: number;
49  value?: string;
50  onSelect?: (index: number, value?: string) => void;
51}
52
53@Component
54struct IconGroup {
55  @State bgColor: Resource = $r('sys.color.ohos_id_color_background')
56  @State isFocus: boolean = false
57  item: OperationOption
58  focusBorderWidth = BORDER_WIDTH
59
60  build() {
61    Row() {
62      Image(this.item.value)
63        .fillColor($r('sys.color.ohos_id_color_primary'))
64        .width(IMAGE_HEIGHT_NUM)
65        .height(IMAGE_HEIGHT_NUM)
66        .focusable(true)
67    }
68    .focusable(true)
69    .width(BUTTON_SIZE)
70    .height(BUTTON_SIZE)
71    .margin({ right: SPACE_MARGIN, bottom: MARGIN_NUM })
72    .justifyContent(FlexAlign.Center)
73    .borderRadius($r('sys.float.ohos_id_corner_radius_clicked'))
74    .backgroundColor(this.bgColor)
75    .onTouch((event) => {
76      if (event.type === TouchType.Down) {
77        this.item.action && this.item.action()
78        this.bgColor = $r('sys.color.ohos_id_color_click_effect')
79      }
80      if (event.type === TouchType.Up) {
81        this.bgColor = $r('sys.color.ohos_id_color_background')
82      }
83    })
84    .onHover((isHover: boolean) => {
85      if (isHover) {
86        this.bgColor = $r('sys.color.ohos_id_color_hover')
87      } else {
88        this.bgColor = $r('sys.color.ohos_id_color_background')
89      }
90    })
91    .border(this.isFocus ?
92      { width: this.focusBorderWidth,
93        color: $r('sys.color.ohos_id_color_emphasize'),
94        style: BorderStyle.Solid
95      } : { width: 0 })
96    .onFocus(() => {
97      this.isFocus = true;
98    })
99    .onBlur(() => {
100      this.isFocus = false;
101    })
102    .onKeyEvent((event) => {
103      if (event.keyCode === 2054 || event.keyCode === 2050) {
104        this.item.action && this.item.action()
105      }
106    })
107  }
108}
109
110@Component
111export struct SubHeader1 {
112  @Prop icon: Resource
113  @Prop primaryTitle: string
114  @Prop secondaryTitle: string
115  @Prop select: SelectOptions
116  @Prop operationType: OperationType = OperationType.BUTTON
117  operationItem: Array<OperationOption>
118  @State isDuplicateLine: boolean = false
119  @State textArrowBgColor: Resource = $r('sys.color.ohos_id_color_background')
120  @State buttonBgColor: Resource = $r('sys.color.ohos_id_color_background')
121  @State iconBgColor: Resource = $r('sys.color.ohos_id_color_background')
122  @State firstIconBgColor: Resource = $r('sys.color.ohos_id_color_background')
123  @State SecondaryIconBgColor: Resource = $r('sys.color.ohos_id_color_background')
124  @State thirdIconBgColor: Resource = $r('sys.color.ohos_id_color_background')
125  @State flag: boolean = false
126  @State isTextArrowFocus: boolean = false
127  @State flexWidth: number = 0
128  @State titleWidth: number = 0
129  @State titleWidth1: number = 0
130  @State isButtonFocus: boolean = false
131  focusBorderWidth = BORDER_WIDTH
132
133  @Builder ListTextStyle($$: { content: ResourceStr }) {
134    Text($$.content)
135      .fontColor($r('sys.color.ohos_id_color_text_secondary'))
136      .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
137      .fontWeight(FontWeight.Medium)
138      .maxLines(DOUBLE_LINE_NUM)
139      .textOverflow({ overflow: TextOverflow.Ellipsis })
140      .constraintSize({ minWidth: this.titleWidth })
141      .margin({ left: $r('sys.float.ohos_id_max_padding_end'), bottom: SPACE_MARGIN, right: MARGIN_NUM }).borderWidth(1)
142  }
143
144  @Builder ListIconStyle($$: { content: ResourceStr }, icon: ResourceStr) {
145    Row() {
146      Image(icon)
147        .width(IMAGE_WIDTH_NUM)
148        .height(IMAGE_WIDTH_NUM)
149        .margin({ right: SPACE_MARGIN })
150      Text($$.content)
151        .fontColor($r('sys.color.ohos_id_color_text_secondary'))
152        .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
153        .fontWeight(FontWeight.Medium)
154        .maxLines(DOUBLE_LINE_NUM)
155        .textOverflow({ overflow: TextOverflow.Ellipsis })
156        .constraintSize({ minWidth: this.titleWidth - CONSTRAINT_WIDTH })
157    }
158    .margin({ left: $r('sys.float.ohos_id_max_padding_end'), bottom: SPACE_MARGIN, right: MARGIN_NUM })
159  }
160
161  @Builder ContentTextStyle($$: { content: ResourceStr }) {
162    Text($$.content)
163      .fontColor($r('sys.color.ohos_id_color_text_primary'))
164      .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
165      .fontWeight(FontWeight.Medium)
166      .maxLines(DOUBLE_LINE_NUM)
167      .maxFontSize($r('sys.float.ohos_id_text_size_sub_title2'))
168      .minFontSize(MIN_FONT_SIZE)
169      .textOverflow({ overflow: TextOverflow.Ellipsis })
170      .constraintSize({ maxWidth: this.titleWidth })
171      .margin({ left: $r('sys.float.ohos_id_max_padding_start'),
172        right: MARGIN_NUM, bottom: SPACE_MARGIN })
173  }
174
175  @Builder SubTextStyle($$: { content: ResourceStr, subContent: ResourceStr }) {
176    Column() {
177      Text($$.content)
178        .fontColor($r('sys.color.ohos_id_color_text_primary'))
179        .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
180        .fontWeight(FontWeight.Medium)
181        .maxLines(SINGLE_LINE_NUM)
182        .maxFontSize($r('sys.float.ohos_id_text_size_sub_title2'))
183        .minFontSize(MIN_FONT_SIZE)
184        .textOverflow({ overflow: TextOverflow.Ellipsis })
185      Text($$.subContent)
186        .fontColor($r('sys.color.ohos_id_color_text_secondary'))
187        .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
188        .fontWeight(FontWeight.Medium)
189        .maxLines(SINGLE_LINE_NUM)
190        .maxFontSize($r('sys.float.ohos_id_text_size_sub_title3'))
191        .minFontSize(MAIN_TEXT_SIZE)
192        .textOverflow({ overflow: TextOverflow.Ellipsis })
193    }
194    .constraintSize({ maxWidth: this.titleWidth })
195    .alignItems(HorizontalAlign.Start)
196    .onAppear(() => {
197      this.isDuplicateLine = true
198    })
199    .margin({ left: $r('sys.float.ohos_id_max_padding_start'),
200      right: MARGIN_NUM, bottom: SPACE_MARGIN })
201  }
202
203  @Builder SelectStyle(selectParam: SelectOptions) {
204    Select(selectParam.options)
205      .selected(selectParam.selected)
206      .value(selectParam.value)
207      .onSelect((index: number, value?: string) => {
208        if (selectParam.onSelect) {
209          selectParam.onSelect(index, value)
210        }
211      })
212      .constraintSize({ maxWidth: this.titleWidth })
213      .margin({ left: $r('sys.float.ohos_id_default_padding_start'), right: MARGIN_NUM})
214  }
215
216  @Builder LoadingProcessStyle() {
217    LoadingProgress()
218      .width(IMAGE_HEIGHT_NUM)
219      .height(IMAGE_HEIGHT_NUM)
220      .focusable(true)
221      .margin({ right: $r('sys.float.ohos_id_default_padding_end'), bottom: MARGIN_NUM })
222  }
223
224  @Builder TextArrowStyle(textArrow: OperationOption) {
225    Row() {
226      Row() {
227        if (textArrow != null) {
228          Text(textArrow.value)
229            .fontColor($r('sys.color.ohos_id_color_text_secondary'))
230            .fontSize($r('sys.float.ohos_id_text_size_body2'))
231            .margin({ right: MARGIN_NUM })
232            .focusable(true)
233            .maxLines(DOUBLE_LINE_NUM)
234        }
235        Image($r('sys.media.ohos_ic_public_arrow_right'))
236          .fillColor($r('sys.color.ohos_id_color_tertiary'))
237          .width(IMAGE_WIDTH)
238          .height(IMAGE_HEIGHT_NUM)
239          .focusable(true)
240      }.margin({ left: SPACE_MARGIN, right: SPACE_MARGIN })
241    }
242    .justifyContent(FlexAlign.End)
243    .focusable(true)
244    .margin({ left:MARGIN_NUM, right: MARGIN_NUM, bottom: MARGIN_NUM })
245    .borderRadius($r('sys.float.ohos_id_corner_radius_subtab'))
246    .backgroundColor(this.textArrowBgColor)
247    .onTouch((event) => {
248      if (event.type === TouchType.Down) {
249        if (textArrow.action) {
250          textArrow.action()
251        }
252        this.textArrowBgColor = $r('sys.color.ohos_id_color_click_effect')
253      }
254      if (event.type === TouchType.Up) {
255        this.textArrowBgColor = $r('sys.color.ohos_id_color_background')
256      }
257    })
258    .onHover((isHover: boolean) => {
259      if (isHover) {
260        this.textArrowBgColor = $r('sys.color.ohos_id_color_hover')
261      } else {
262        this.textArrowBgColor = $r('sys.color.ohos_id_color_background')
263      }
264    })
265    .border(this.isTextArrowFocus ?
266      { width: this.focusBorderWidth,
267        color: $r('sys.color.ohos_id_color_focused_outline'),
268        style: BorderStyle.Solid
269      } : { width: 0 })
270    .onFocus(() => {
271      this.isTextArrowFocus = true;
272    })
273    .onBlur(() => {
274      this.isTextArrowFocus = false;
275    })
276    .onKeyEvent((event) => {
277      if (event.keyCode === 2054 || event.keyCode === 2050) {
278        textArrow.action && textArrow.action()
279      }
280    })
281  }
282
283  @Builder ButtonStyle(button: OperationOption) {
284    Row() {
285      if (button != null) {
286        Text(button.value)
287          .maxLines(1)
288          .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
289          .fontSize($r('sys.float.ohos_id_text_size_button2'))
290          .fontWeight(FontWeight.Medium)
291          .margin({ left: SPACE_MARGIN, right: SPACE_MARGIN })
292          .focusable(true)
293      }
294    }
295    .onAreaChange((oldValue: Area, newValue: Area) => {
296      Number(parseInt(newValue.width.toString(), 0))
297      console.log('wy buttonStyle1'+Number(parseInt(newValue.width.toString(), 0)))
298    })
299    .justifyContent(FlexAlign.End)
300    .alignItems(VerticalAlign.Center)
301    .constraintSize({ maxWidth: this.flexWidth-this.titleWidth1 + 36 })
302    .focusable(true)
303    .height(BUTTON_HEIGHT)
304    .margin({ left: SPACE_MARGIN, right: MARGIN_NUM })
305    .borderRadius(IMAGE_WIDTH_NUM)
306    .backgroundColor(this.buttonBgColor)
307    .onTouch((event) => {
308      if (event.type === TouchType.Down) {
309        if (button.action) {
310          button.action()
311        }
312        this.buttonBgColor = $r('sys.color.ohos_id_color_click_effect')
313      }
314      if (event.type === TouchType.Up) {
315        this.buttonBgColor = $r('sys.color.ohos_id_color_background')
316      }
317    })
318    .onHover((isHover: boolean) => {
319      if (isHover) {
320        this.buttonBgColor = $r('sys.color.ohos_id_color_hover')
321      } else {
322        this.buttonBgColor = $r('sys.color.ohos_id_color_background')
323      }
324    })
325    .border(this.isButtonFocus ?
326      { width: this.focusBorderWidth,
327        color: $r('sys.color.ohos_id_color_focused_outline'),
328        style: BorderStyle.Solid
329      } : { width: 0 })
330    .onFocus(() => {
331      this.isButtonFocus = true;
332    })
333    .onBlur(() => {
334      this.isButtonFocus = false;
335    })
336    .onKeyEvent((event) => {
337      if (event.keyCode === 2054 || event.keyCode === 2050) {
338        button.action && button.action()
339      }
340    })
341  }
342
343  build() {
344    Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.End }) {
345      Row() {
346        if (this.secondaryTitle != null && this.icon != null) {
347          this.ListIconStyle({ content: this.secondaryTitle }, this.icon)
348        } else if (this.secondaryTitle != null && this.primaryTitle != null) {
349          this.SubTextStyle({ content: this.primaryTitle, subContent: this.secondaryTitle })
350        } else if (this.secondaryTitle != null) {
351          this.ListTextStyle({ content: this.secondaryTitle })
352        } else if (this.select != null) {
353          this.SelectStyle(this.select)
354        } else if (this.primaryTitle != null) {
355          this.ContentTextStyle({ content: this.primaryTitle })
356        }
357      }
358      .onAreaChange((oldValue: Area, newValue: Area) => {
359        this.titleWidth1 = Number(parseInt(newValue.width.toString(), 0))
360        console.log('wy titleWidth1'+this.titleWidth.toString())
361      })
362
363      Row() {
364        if (this.operationType === OperationType.BUTTON && this.operationItem != null) {
365          this.ButtonStyle(this.operationItem[0] )
366        }
367        if (this.operationType === OperationType.ICON_GROUP && this.operationItem != null) {
368          Row() {
369            ForEach(this.operationItem, (item, index?: number) => {
370              if (index == 0) {
371                IconGroup({ item: item })
372              }
373              if (index == 1) {
374                IconGroup({ item: item })
375              }
376              if (index == 2) { // Image count
377                IconGroup({ item: item })
378              }
379            })
380          }
381        }
382        if (this.operationType === OperationType.TEXT_ARROW && this.operationItem != null) {
383          this.TextArrowStyle(this.operationItem[0])
384        }
385        if (this.operationType === OperationType.LOADING) {
386          this.LoadingProcessStyle()
387        }
388      }
389    }
390    .onAreaChange((oldValue: Area, newValue: Area) => {
391      let flexWidth = Number(parseInt(newValue.width.toString(), 0))
392      this.flexWidth = flexWidth - CONSTRAINT_NUM
393      this.titleWidth = this.flexWidth / DIVIDEND_WIDTH * BORDER_WIDTH
394      console.log('wy flexWidth'+this.flexWidth.toString())
395    })
396    .padding({ right: $r('sys.float.ohos_id_default_padding_end') })
397    .height(this.isDuplicateLine ? DOUBLE_LINE_HEIGHT : SINGLE_LINE_HEIGHT)
398  }
399}