• 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  aboutToDisappear() {
125    this.appBroadcast.off(BroadcastConstants.RESET_TAB_SELECTED_STATUE, null);
126  }
127
128  build() {
129    Flex({
130      direction: FlexDirection.Column,
131      alignItems: ItemAlign.Center,
132      justifyContent: FlexAlign.Center
133    }) {
134      Stack() {
135        Image(this.tabItem.getIcon(this.isSelected))
136          .height($r('app.float.icon_size'))
137          .width($r('app.float.icon_size'))
138          .objectFit(ImageFit.Fill)
139      }
140
141      Text(this.tabItem.name)
142        .fontSize($r('sys.float.ohos_id_text_size_caption1'))
143        .fontFamily($r('app.string.id_text_font_family_medium'))
144        .fontColor(this.tabItem.getTextColor(this.isSelected))
145        .padding({
146          top: $r('app.float.tab_bar_text_padding_top'),
147          right: $r('app.float.tab_bar_text_padding_horizontal'),
148          left: $r('app.float.tab_bar_text_padding_horizontal')
149        })
150    }
151    .onClick(() => {
152      this.onTabSelected && this.onTabSelected(this.index);
153      this.tabItem.isSelected = true;
154      this.appBroadcast.emit(BroadcastConstants.RESET_TAB_SELECTED_STATUE, [this.index]);
155    })
156  }
157}
158
159// For Album Set
160@Component
161export struct TabBarForAlbumSet {
162  private TAG: string = 'TabBarForAlbumSet'
163  @Consume isTabBarShow: boolean;
164  private currentIndex: number;
165  private tabs: TabItemWithText[] = [];
166  private controller: TabsController;
167  @State tabWidth: string = '100%';
168  @State tabCol: Resource = $r('app.float.album_tab_col_4_gap');
169  @StorageLink('isSidebar') isSidebar: boolean = screenManager.isSidebar();
170
171  aboutToAppear(): void {
172    this.onTabSelected = this.onTabSelected.bind(this);
173    this.tabs[this.currentIndex].isSelected = true;
174    this.tabs.forEach((tab: TabItemWithText) => {
175      Log.info(this.TAG, `${JSON.stringify(tab.name)}, ${tab.isSelected}`);
176    });
177    let col = screenManager.getScreenColumns();
178    if (col < ColumnSize.COLUMN_EIGHT) {
179      this.tabWidth = '100%';
180      this.tabCol = $r('app.float.album_tab_col_4_gap');
181    } else {
182      let sideWidth = this.isSidebar ? Constants.TAB_BAR_WIDTH : 0;
183      this.tabWidth = (screenManager.getWinWidth() - sideWidth) / Constants.NUMBER_2 + 'vp';
184      this.tabCol = $r('app.float.album_tab_col_8_gap');
185    }
186    Log.info(this.TAG, `album tabs item width: ${this.tabWidth}, col: ${col}`);
187  }
188
189  private onTabSelected(index: number) {
190    Log.info(this.TAG, `this.currentIndex: ${this.currentIndex} index: ${index}`);
191    this.currentIndex = index;
192    this.controller.changeIndex(this.currentIndex);
193    this.tabs.forEach((tab: TabItemWithText) => {
194      tab.isSelected = false;
195    })
196    Log.info(this.TAG, `select ${this.currentIndex}`);
197  }
198
199  build() {
200    Flex({
201      direction: FlexDirection.Row,
202      justifyContent: FlexAlign.Center,
203      alignItems: ItemAlign.Start
204    }) {
205      Grid() {
206        ForEach(this.tabs, (tab: TabItemWithText) => {
207          GridItem() {
208            TabWithText({
209              tabItemWithText: tab,
210              index: this.tabs.indexOf(tab),
211              onTabSelected: this.onTabSelected
212            })
213          }
214        }, tab => tab.name.id)
215      }
216      .width(this.tabWidth)
217      .columnsTemplate('1fr '.repeat(this.tabs.length))
218      .columnsGap(this.tabCol)
219    }
220    .width('100%')
221    .height($r('app.float.album_set_tab_bar_height'))
222    .padding({ left: $r('app.float.max_padding_start'), right: $r('app.float.max_padding_end') })
223    .backgroundColor($r('app.color.default_background_color'))
224  }
225}
226
227// single tab which only has text
228// For Album Set
229@Component
230struct TabWithText {
231  private TAG: string = 'TabWithText'
232  @Consume isAlbumSetSelectedMode: boolean;
233  tabItemWithText: TabItemWithText;
234  @State isSelected: boolean = false;
235  @State TabWidth: number = 0;
236  index: number;
237  onTabSelected: Function;
238  appBroadcast: Broadcast = broadcastManager.getBroadcast();
239
240  aboutToAppear(): void {
241    // Determine the length of the underline based on the font length
242    if (this.index == 0) {
243      this.TabWidth = px2vp(fp2px(Constants.TEXT_SIZE_SUB_TITLE2)) * 2;
244    } else {
245      this.TabWidth = px2vp(fp2px(Constants.TEXT_SIZE_SUB_TITLE2)) * 4;
246    }
247    Log.info(this.TAG, `index is ${this.index} and TabWidth is ${this.TabWidth}`);
248    this.isSelected = this.tabItemWithText.isSelected;
249    this.appBroadcast.on(BroadcastConstants.RESET_TAB_SELECTED_TEXT, (pageNumber: number) => {
250      this.isSelected = this.index == pageNumber;
251    })
252  }
253
254  build() {
255    Flex({
256      direction: FlexDirection.Column,
257      justifyContent: FlexAlign.Center,
258      alignItems: ItemAlign.Center
259    }) {
260      Text(this.tabItemWithText.name)
261        .fontSize(this.tabItemWithText.getTextSize(this.isSelected))
262        .fontWeight(this.tabItemWithText.getTextWeight(this.isSelected))
263        .fontColor(this.tabItemWithText.getTextColor(this.isSelected))
264        .maxLines(1)
265        .margin({ top: $r('app.float.tab_bar_line_margin_top'),
266          left: $r('app.float.single_tab_margin'),
267          right: $r('app.float.single_tab_margin'),
268          bottom: $r('app.float.tab_bar_line_margin_top') })
269      Column()
270        .width(this.TabWidth)
271        .height($r('app.float.tab_bar_line_height'))
272        .borderRadius($r('app.float.tab_bar_line_radius'))
273        .backgroundColor(this.tabItemWithText.getTextColor(this.isSelected))
274        .visibility(this.tabItemWithText.isSelected ? Visibility.Visible : Visibility.Hidden)
275    }
276    .height('100%')
277    .width('100%')
278    .onClick(() => {
279      if (!this.isAlbumSetSelectedMode) {
280        this.onTabSelected && this.onTabSelected(this.index)
281        this.tabItemWithText.isSelected = true;
282        this.appBroadcast.emit(BroadcastConstants.RESET_TAB_SELECTED_TEXT, [this.index]);
283      }
284    })
285  }
286}