• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { Log } from '@ohos/base/src/main/ets/utils/Log';
17import { TabItem, TabItemWithText } from '../model/common/TabItem';
18import broadcastManager from '@ohos/base/src/main/ets/manager/BroadcastManager';
19import { Broadcast } from '@ohos/base/src/main/ets/utils/Broadcast';
20import { BroadcastConstants } from '@ohos/base/src/main/ets/constants/BroadcastConstants';
21import { Constants } from '../model/common/Constants';
22import screenManager, { ColumnSize } from '@ohos/base/src/main/ets/manager/ScreenManager';
23
24export enum DEVICE_TYPE {
25  DEVICE_PHONE,
26  DEVICE_PAD
27}
28
29@Component
30export struct TabBar {
31  private TAG: string = 'TabBar';
32  @Consume isSelectedMode: boolean;
33  @Consume isAlbumSetSelectedMode: boolean;
34  private currentIndex: number;
35  @StorageLink('isSidebar') isSidebar: boolean = screenManager.isSidebar();
36  private tabs: TabItem[] = [
37    new TabItem($r('app.string.tab_timeline'), $r('app.media.ic_photos'), $r("app.media.ic_photos_active"), false),
38    new TabItem($r('app.string.tab_albums'), $r('app.media.ic_albums'), $r("app.media.ic_albums_active"), false)
39  ];
40  private controller: TabsController;
41  private appBroadcast: Broadcast = broadcastManager.getBroadcast();
42  deviceType: DEVICE_TYPE = DEVICE_TYPE.DEVICE_PHONE;
43
44  aboutToAppear(): void {
45    this.onTabSelected = this.onTabSelected.bind(this);
46    this.tabs[this.currentIndex].isSelected = true;
47    this.tabs.forEach((tab: TabItem) => {
48      Log.info(this.TAG, `${JSON.stringify(tab.name)} , ${tab.iconSelected}`);
49    });
50  }
51
52  private onTabSelected(index: number) {
53    Log.debug(this.TAG, `this.currentIndex: ${this.currentIndex} index: ${index}`);
54    if (this.currentIndex == index) {
55      Log.error(this.TAG, `it is same: ${index}`);
56      this.appBroadcast.emit(BroadcastConstants.RESET_ZERO, [index]);
57    }
58    this.currentIndex = index;
59    this.controller.changeIndex(this.currentIndex);
60    this.tabs.forEach((tab: TabItem) => {
61      tab.isSelected = false;
62    })
63
64    Log.info(this.TAG, `select ${this.currentIndex}`);
65  }
66
67  build() {
68    if (this.isSidebar) {
69      Flex({
70        direction: FlexDirection.Column,
71        alignItems: ItemAlign.Center,
72        justifyContent: FlexAlign.Center
73      }) {
74        Column() {
75          ForEach(this.tabs, (tab: TabItem) => {
76            Stack() {
77              Tab({ tabItem: tab, index: this.tabs.indexOf(tab), onTabSelected: this.onTabSelected })
78            }.layoutWeight(1)
79          }, tab => tab.name.id)
80        }
81        .height(DEVICE_TYPE.DEVICE_PAD == this.deviceType ? $r('app.float.horizontal_width') : '100%')
82      }
83      .markAnchor({ x: '0%', y: '0%' })
84      .position({ x: '0%', y: '0%' })
85      .width($r('app.float.tab_bar_width'))
86      .backgroundColor($r('app.color.default_background_color'))
87    } else {
88      Flex({
89        direction: FlexDirection.Row,
90        alignItems: ItemAlign.Center,
91        justifyContent: FlexAlign.Center
92      }) {
93        ForEach(this.tabs, (tab: TabItem) => {
94          Stack() {
95            Tab({ tabItem: tab, index: this.tabs.indexOf(tab), onTabSelected: this.onTabSelected })
96          }.layoutWeight(1)
97        }, tab => tab.name.id)
98      }
99      .markAnchor({ x: '0%', y: '100%' })
100      .position({ x: '0%', y: '100%' })
101      .visibility((this.isSelectedMode || this.isAlbumSetSelectedMode) ? Visibility.None : Visibility.Visible)
102      .height('56vp')
103      .backgroundColor($r('app.color.default_background_color'))
104    }
105  }
106}
107
108// single tab
109@Component
110struct Tab {
111  tabItem: TabItem;
112  @State isSelected: boolean = false;
113  index: number;
114  onTabSelected: Function;
115  appBroadcast: Broadcast = broadcastManager.getBroadcast();
116
117  aboutToAppear() {
118    this.isSelected = this.tabItem.isSelected;
119    this.appBroadcast.on(BroadcastConstants.RESET_TAB_SELECTED_STATUE, (pageNumber: number) => {
120      this.isSelected = this.index == pageNumber;
121    })
122  }
123
124  build() {
125    Flex({
126      direction: FlexDirection.Column,
127      alignItems: ItemAlign.Center,
128      justifyContent: FlexAlign.Center
129    }) {
130      Stack() {
131        Image(this.tabItem.getIcon(this.isSelected))
132          .height($r('app.float.icon_size'))
133          .width($r('app.float.icon_size'))
134          .objectFit(ImageFit.Fill)
135      }
136
137      Text(this.tabItem.name)
138        .fontSize($r('sys.float.ohos_id_text_size_caption1'))
139        .fontFamily($r('app.string.id_text_font_family_medium'))
140        .fontColor(this.tabItem.getTextColor(this.isSelected))
141        .padding({
142          top: $r('app.float.tab_bar_text_padding_top'),
143          right: $r('app.float.tab_bar_text_padding_horizontal'),
144          left: $r('app.float.tab_bar_text_padding_horizontal')
145        })
146    }
147    .onClick(() => {
148      this.onTabSelected && this.onTabSelected(this.index);
149      this.tabItem.isSelected = true;
150      this.appBroadcast.emit(BroadcastConstants.RESET_TAB_SELECTED_STATUE, [this.index]);
151    })
152  }
153}
154
155// For Album Set
156@Component
157export struct TabBarForAlbumSet {
158  private TAG: string = 'TabBarForAlbumSet'
159  @Consume isTabBarShow: boolean;
160  private currentIndex: number;
161  private tabs: TabItemWithText[] = [];
162  private controller: TabsController;
163  @State tabWidth: string = '100%';
164  @State tabCol: Resource = $r('app.float.album_tab_col_4_gap');
165  @StorageLink('isSidebar') isSidebar: boolean = screenManager.isSidebar();
166
167  aboutToAppear(): void {
168    this.onTabSelected = this.onTabSelected.bind(this);
169    this.tabs[this.currentIndex].isSelected = true;
170    this.tabs.forEach((tab: TabItemWithText) => {
171      Log.info(this.TAG, `${JSON.stringify(tab.name)}, ${tab.isSelected}`);
172    });
173    let col = screenManager.getScreenColumns();
174    if (col < ColumnSize.COLUMN_EIGHT) {
175      this.tabWidth = '100%';
176      this.tabCol = $r('app.float.album_tab_col_4_gap');
177    } else {
178      let sideWidth = this.isSidebar ? Constants.TAB_BAR_WIDTH : 0;
179      this.tabWidth = (screenManager.getWinWidth() - sideWidth) / Constants.NUMBER_2 + 'vp';
180      this.tabCol = $r('app.float.album_tab_col_8_gap');
181    }
182    Log.info(this.TAG, `album tabs item width: ${this.tabWidth}, col: ${col}`);
183  }
184
185  private onTabSelected(index: number) {
186    Log.info(this.TAG, `this.currentIndex: ${this.currentIndex} index: ${index}`);
187    this.currentIndex = index;
188    this.controller.changeIndex(this.currentIndex);
189    this.tabs.forEach((tab: TabItemWithText) => {
190      tab.isSelected = false;
191    })
192    Log.info(this.TAG, `select ${this.currentIndex}`);
193  }
194
195  build() {
196    Flex({
197      direction: FlexDirection.Row,
198      justifyContent: FlexAlign.Center,
199      alignItems: ItemAlign.Start
200    }) {
201      Grid() {
202        ForEach(this.tabs, (tab: TabItemWithText) => {
203          GridItem() {
204            TabWithText({
205              tabItemWithText: tab,
206              index: this.tabs.indexOf(tab),
207              onTabSelected: this.onTabSelected
208            })
209          }
210        }, tab => tab.name.id)
211      }
212      .width(this.tabWidth)
213      .columnsTemplate('1fr '.repeat(this.tabs.length))
214      .columnsGap(this.tabCol)
215    }
216    .width('100%')
217    .height($r('app.float.album_set_tab_bar_height'))
218    .padding({ left: $r('app.float.max_padding_start'), right: $r('app.float.max_padding_end') })
219    .backgroundColor($r('app.color.default_background_color'))
220  }
221}
222
223// single tab which only has text
224// For Album Set
225@Component
226struct TabWithText {
227  private TAG: string = 'TabWithText'
228  @Consume isAlbumSetSelectedMode: boolean;
229  tabItemWithText: TabItemWithText;
230  @State isSelected: boolean = false;
231  @State TabWidth: number = 0;
232  index: number;
233  onTabSelected: Function;
234  appBroadcast: Broadcast = broadcastManager.getBroadcast();
235
236  aboutToAppear(): void {
237    // Determine the length of the underline based on the font length
238    if (this.index == 0) {
239      this.TabWidth = px2vp(fp2px(Constants.TEXT_SIZE_SUB_TITLE2)) * 2;
240    } else {
241      this.TabWidth = px2vp(fp2px(Constants.TEXT_SIZE_SUB_TITLE2)) * 4;
242    }
243    Log.info(this.TAG, `index is ${this.index} and TabWidth is ${this.TabWidth}`);
244    this.isSelected = this.tabItemWithText.isSelected;
245    this.appBroadcast.on(BroadcastConstants.RESET_TAB_SELECTED_TEXT, (pageNumber: number) => {
246      this.isSelected = this.index == pageNumber;
247    })
248  }
249
250  build() {
251    Flex({
252      direction: FlexDirection.Column,
253      justifyContent: FlexAlign.Center,
254      alignItems: ItemAlign.Center
255    }) {
256      Text(this.tabItemWithText.name)
257        .fontSize(this.tabItemWithText.getTextSize(this.isSelected))
258        .fontWeight(this.tabItemWithText.getTextWeight(this.isSelected))
259        .fontColor(this.tabItemWithText.getTextColor(this.isSelected))
260        .maxLines(1)
261        .margin({ top: $r('app.float.tab_bar_line_margin_top'),
262          left: $r('app.float.single_tab_margin'),
263          right: $r('app.float.single_tab_margin'),
264          bottom: $r('app.float.tab_bar_line_margin_top') })
265      Column()
266        .width(this.TabWidth)
267        .height($r('app.float.tab_bar_line_height'))
268        .borderRadius($r('app.float.tab_bar_line_radius'))
269        .backgroundColor(this.tabItemWithText.getTextColor(this.isSelected))
270        .visibility(this.tabItemWithText.isSelected ? Visibility.Visible : Visibility.Hidden)
271    }
272    .height('100%')
273    .width('100%')
274    .onClick(() => {
275      if (!this.isAlbumSetSelectedMode) {
276        this.onTabSelected && this.onTabSelected(this.index)
277        this.tabItemWithText.isSelected = true;
278        this.appBroadcast.emit(BroadcastConstants.RESET_TAB_SELECTED_TEXT, [this.index]);
279      }
280    })
281  }
282}