1/** 2 * Copyright (c) 2021-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, Trace, StyleConstants, CommonConstants, AppMenu, MenuInfo, localEventManager, EventConstants } from '@ohos/common'; 17import SwiperPage from './SwiperPage'; 18 19const TAG = "GridSwiper"; 20const APP_INFO_REFRESH_DELAY = 1000; 21 22@Component 23export default struct GridSwiper { 24 @StorageLink('NavigationBarStatusValue') navigationBarStatusValue: boolean = false; 25 @StorageLink('isDesktopLoadFinished') desktopLoadFinished: boolean = false; 26 @Prop gridConfig: string; 27 @StorageLink('pageIndex') pageIndex: number = 0; 28 private mPageDesktopViewModel; 29 @StorageLink('appListInfo') @Watch('updatePageList') appListInfo: { 30 appGridInfo: [[]] 31 } = { appGridInfo: [[]] }; 32 @State pageList: number[] = [0]; 33 private swiperController: SwiperController = new SwiperController(); 34 private dialogController: CustomDialogController; 35 36 aboutToAppear(): void { 37 this.mPageDesktopViewModel.setSwiperController(this.swiperController); 38 } 39 40 aboutToDisappear(): void { 41 Log.showInfo(TAG, 'aboutToDisappear'); 42 delete this.dialogController; 43 this.dialogController = null; 44 this.swiperController = null; 45 } 46 47 private updatePageList(): void { 48 if (this.pageList.length !== this.appListInfo.appGridInfo?.length) { 49 if (this.pageList.length < this.appListInfo.appGridInfo.length) { 50 for (let i = this.pageList.length - 1; i < this.appListInfo.appGridInfo.length; i++) { 51 if (this.pageList.indexOf(i) === -1) { 52 this.pageList.push(i); 53 } 54 } 55 } 56 if (this.pageList.length > this.appListInfo.appGridInfo.length) { 57 for (let i = this.pageList.length - 1; i >= this.appListInfo.appGridInfo.length; i--) { 58 if (this.pageList.indexOf(i) !== -1) { 59 this.pageList.splice(i, 1); 60 } 61 } 62 } 63 } 64 } 65 66 private buildLog(): boolean { 67 let isDesktopLoadFinished = AppStorage.Get('isDesktopLoadFinished'); 68 Log.showDebug(TAG, `build start ${isDesktopLoadFinished} page ${this.pageIndex}`); 69 return isDesktopLoadFinished == true; 70 } 71 72 @Builder MenuBuilder() { 73 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 74 AppMenu({ 75 getMenuInfoList: this.getMenu.bind(this), 76 }) 77 } 78 .width(StyleConstants.CONTEXT_MENU_WIDTH) 79 .borderRadius(StyleConstants.DEFAULT_12) 80 } 81 82 private getMenu(): MenuInfo[] { 83 let menuInfoList = new Array<MenuInfo>(); 84 let setting = new MenuInfo(); 85 setting.menuType = CommonConstants.MENU_TYPE_FIXED 86 setting.menuImgSrc = "/common/pics/ic_public_settings.svg" 87 setting.menuText = $r('app.string.into_settings') 88 setting.onMenuClick = () => { 89 Trace.start(Trace.CORE_METHOD_START_SETTINGS); 90 this.mPageDesktopViewModel.intoSetting(); 91 } 92 menuInfoList.push(setting); 93 94 let addOrDeleteBlankPage = new MenuInfo(); 95 addOrDeleteBlankPage.menuType = CommonConstants.MENU_TYPE_FIXED 96 addOrDeleteBlankPage.menuImgSrc = this.mPageDesktopViewModel.getBlankPageBtnIcon() 97 addOrDeleteBlankPage.menuText = this.mPageDesktopViewModel.getBlankPageBtnStr() 98 addOrDeleteBlankPage.onMenuClick = () => { 99 this.mPageDesktopViewModel.addOrDeleteBlankPage(); 100 } 101 menuInfoList.push(addOrDeleteBlankPage); 102 return menuInfoList; 103 } 104 105 itemMove(moveX: number, moveY: number){ 106 const hotArea: number = 12; 107 let screenWidth: number = AppStorage.Get('screenWidth') ?? 0; 108 let screenHeight: number = AppStorage.Get('screenHeight') ?? 0; 109 const isSwappingPage: boolean = AppStorage.Get('isSwappingPage'); 110 if (isSwappingPage || !screenWidth || !screenHeight) { 111 return; 112 } 113 let curPageIndex: number = AppStorage.Get('pageIndex'); 114 if (moveX < hotArea && curPageIndex > 0 && moveY < screenHeight) { 115 this.mPageDesktopViewModel.showPrevious(); 116 this.movingIconSwapPageDelay(); 117 } 118 if (moveX > (screenWidth - hotArea) && moveY < screenHeight) { 119 let cachePageIndex = this.mPageDesktopViewModel.getGridPageCount(); 120 if (curPageIndex == cachePageIndex - 1 && !this.mPageDesktopViewModel.isBlankPage()) { 121 this.mPageDesktopViewModel.addBlankPage(true); 122 } else if(curPageIndex < cachePageIndex - 1) { 123 this.mPageDesktopViewModel.showNext(); 124 } 125 this.movingIconSwapPageDelay(); 126 } 127 } 128 129 /** 130 * Increase delay when dragging app to other page. 131 */ 132 movingIconSwapPageDelay() { 133 AppStorage.SetOrCreate('isSwappingPage', true); 134 setTimeout(() => { 135 AppStorage.SetOrCreate('isSwappingPage', false); 136 }, APP_INFO_REFRESH_DELAY); 137 } 138 139 build() { 140 Column() { 141 if (this.buildLog()) {} 142 if (this.desktopLoadFinished) { 143 Swiper(this.swiperController) { 144 ForEach(this.pageList, (item, index: number) => { 145 if (AppStorage.Get('deviceType') == CommonConstants.DEFAULT_DEVICE_TYPE) { 146 Column() { 147 SwiperPage({ 148 swiperPage: index.valueOf(), 149 gridConfig: this.gridConfig, 150 mPageDesktopViewModel: this.mPageDesktopViewModel 151 }) 152 } 153 .gesture( 154 LongPressGesture({ repeat: false }) 155 .onAction((event: GestureEvent) => { 156 this.dialogController.open() 157 }) 158 ) 159 .bindContextMenu(this.MenuBuilder, ResponseType.RightClick) 160 } else { 161 SwiperPage({ 162 swiperPage: index.valueOf(), 163 gridConfig: this.gridConfig, 164 mPageDesktopViewModel: this.mPageDesktopViewModel 165 }) 166 .bindContextMenu(this.MenuBuilder, ResponseType.LongPress) 167 .bindContextMenu(this.MenuBuilder, ResponseType.RightClick) 168 } 169 }, item => item) 170 } 171 .padding({ 172 top: this.navigationBarStatusValue ? 173 this.mPageDesktopViewModel.getPageDesktopStyleConfig().mDesktopMarginTop : 174 this.mPageDesktopViewModel.getPageDesktopStyleConfig().mDesktopMarginTop + 0 175 }) 176 .height(StyleConstants.PERCENTAGE_100) 177 .width(StyleConstants.PERCENTAGE_100) 178 .indicatorStyle({ 179 selectedColor: StyleConstants.DEFAULT_FONT_COLOR 180 }) 181 .loop(false) 182 .index(this.pageIndex) 183 .onChange((index) => { 184 this.pageIndex = index; 185 Log.showInfo(TAG, `swiper change to page ${index}`); 186 localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE, null); 187 }) 188 } 189 } 190 .alignItems(HorizontalAlign.Center) 191 .justifyContent(FlexAlign.Center) 192 .height(StyleConstants.PERCENTAGE_100) 193 .width(StyleConstants.PERCENTAGE_100) 194 .onDragMove((event: DragEvent, extraParams: string) => { 195 Log.showInfo(TAG, `onDragMove event: [${event.getX()}, ${event.getY()}]`); 196 if (!AppStorage.Get('isDrag')) return; 197 if (AppStorage.Get('deviceType') === CommonConstants.DEFAULT_DEVICE_TYPE 198 || (AppStorage.Get('deviceType') !== CommonConstants.DEFAULT_DEVICE_TYPE 199 && AppStorage.Get('dragItemType') === CommonConstants.DRAG_FROM_DESKTOP)) { 200 this.itemMove(event.getX(), event.getY()); 201 } 202 }) 203 } 204}