1// @ts-nocheck 2/** 3 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import { AppMenu } from '@ohos/common'; 18import { AppIcon } from '@ohos/common'; 19import { DockItemInfo } from '@ohos/common'; 20import { CommonConstants } from '@ohos/common'; 21import { StyleConstants } from '@ohos/common'; 22import { ResourceManager } from '@ohos/common'; 23import { Log } from '@ohos/common'; 24import { SmartDockStyleConfig } from '../config/SmartDockStyleConfig'; 25 26let mSmartDockStyleConfig: SmartDockStyleConfig = null; 27const TAG = 'ResidentLayout'; 28 29@Component 30export default struct ResidentLayout { 31 @StorageLink('dockPadding') dockPadding: { 32 right: number, 33 left: number, 34 top: number, 35 bottom: number 36 } = { right: 0, left: 0, top: 0, bottom: 0 }; 37 @StorageLink('residentList') @Watch('onDockListChange') appList: Array<DockItemInfo> = []; 38 mSmartDockStyleConfig: SmartDockStyleConfig; 39 onItemClick: Function = null; 40 buildMenu: Function = null; 41 onDockListChangeFunc: Function = null; 42 43 aboutToAppear(): void { 44 mSmartDockStyleConfig = this.mSmartDockStyleConfig; 45 this.onDockListChange(); 46 } 47 48 aboutToDisappear(): void { 49 this.onItemClick = null; 50 this.buildMenu = null; 51 this.onDockListChangeFunc = null; 52 } 53 54 getListWidth(): number { 55 let residentMaxNum = this.mSmartDockStyleConfig.mMaxDockNum; 56 let width = 0.0; 57 if (AppStorage.Get("deviceType") == CommonConstants.DEFAULT_DEVICE_TYPE) { 58 Log.showDebug(TAG, `getListWidth mDockPadding: ${this.mSmartDockStyleConfig.mDockPadding}, mMaxNum: ${residentMaxNum}`); 59 width = this.mSmartDockStyleConfig.mDockPadding * 2 + residentMaxNum * (this.mSmartDockStyleConfig.mListItemWidth) + (residentMaxNum - 1) * (this.mSmartDockStyleConfig.mListItemGap); 60 Log.showDebug(TAG, `getListWidth width: ${width}`); 61 } else { 62 if (this.appList == null || this.appList.length === 0) { 63 } else { 64 let num = this.appList.length; 65 if (num > residentMaxNum) { 66 num = residentMaxNum; 67 } 68 width = this.mSmartDockStyleConfig.mDockPadding * 2 + num * (this.mSmartDockStyleConfig.mListItemWidth) + (num - 1) * (this.mSmartDockStyleConfig.mListItemGap); 69 } 70 } 71 return width; 72 } 73 74 private onDockListChange() { 75 this.onDockListChangeFunc(); 76 } 77 78 build() { 79 if (this.getListWidth && this.getListWidth() !== 0) { 80 Row() { 81 List({ space: this.appList.length == 0 ? 0 : this.mSmartDockStyleConfig.mListItemGap }) { 82 ForEach(this.appList, (item) => { 83 ListItem() { 84 AppItem({ 85 appInfo: item, 86 buildMenu: this.buildMenu, 87 onItemClick: this.onItemClick 88 }) 89 } 90 }, (item) => JSON.stringify(item)) 91 } 92 .height('100%') 93 .animation({ 94 curve: Curve.Friction 95 }) 96 .listDirection(this.mSmartDockStyleConfig.mListDirection) 97 .editMode(false) 98 } 99 .backgroundColor(this.mSmartDockStyleConfig.mBackgroundColor) 100 .borderRadius(this.mSmartDockStyleConfig.mDockRadius) 101 .backdropBlur(this.mSmartDockStyleConfig.mBackdropBlur) 102 .padding(this.appList.length == 0 ? this.mSmartDockStyleConfig.mDockPadding : this.dockPadding) 103 .width(this.getListWidth()) 104 .height(this.mSmartDockStyleConfig.mDockHeight) 105 .justifyContent(FlexAlign.Center) 106 .onDragEnter((event: DragEvent, extraParams: string) => { 107 Log.showDebug(TAG, `onDragEnter extraParams: ${extraParams}, event: [${event.getX()}, ${event.getY()}]`); 108 }) 109 .onDragMove((event: DragEvent, extraParams: string) => { 110 Log.showDebug(TAG, `onDragMove event: [${event.getX()}, ${event.getY()}]`); 111 }) 112 .onDragLeave((event: DragEvent, extraParams: string) => { 113 Log.showDebug(TAG, `onDragLeave event: [${event.getX()}, ${event.getY()}]`); 114 }) 115 .onDrop((event: DragEvent, extraParams: string) => { 116 Log.showInfo(TAG, `onDrop event: [${event.getX()}, ${event.getY()}]`); 117 const dragResult = globalThis.SmartDockDragHandler.onDragDrop(event.getX(), event.getY()); 118 AppStorage.SetOrCreate('selectAppIndex', null); 119 AppStorage.SetOrCreate('isDrag', false); 120 if (!dragResult) { 121 AppStorage.SetOrCreate('dragItemInfo', {}); 122 } else { 123 // Wait for the UI rendering to end. 124 setTimeout(() => { 125 AppStorage.SetOrCreate('dragItemInfo', {}); 126 }, 50); 127 } 128 }) 129 } 130 } 131} 132 133@Component 134struct AppItem { 135 @StorageLink('dragItemInfo') smartDragItemInfo: any = {}; 136 @StorageLink('dragItemType') dragItemType: number = CommonConstants.DRAG_FROM_DOCK; 137 @State isShow: boolean = false; 138 onItemClick: Function = null; 139 appInfo: DockItemInfo = null; 140 buildMenu: Function = null; 141 private menuInfo; 142 143 @Builder dragLayerBuilder() { 144 Column() { 145 AppIcon({ 146 iconSize: mSmartDockStyleConfig.mIconSize * 1.05, 147 iconId: this.appInfo.appIconId, 148 bundleName: this.appInfo.bundleName, 149 moduleName: this.appInfo.moduleName, 150 icon: ResourceManager.getInstance().getCachedAppIcon(this.appInfo.appIconId, 151 this.appInfo.bundleName, this.appInfo.moduleName), 152 badgeNumber: CommonConstants.BADGE_DISPLAY_HIDE 153 }) 154 } 155 } 156 157 aboutToAppear(): void { 158 this.menuInfo = this.buildMenu(this.appInfo); 159 } 160 161 aboutToDisappear(): void { 162 this.buildMenu = null; 163 this.onItemClick = null; 164 } 165 166 private getLongPress(): boolean { 167 return AppStorage.Get('isLongPress'); 168 } 169 170 @Builder MenuBuilder() { 171 Column() { 172 AppMenu({ 173 menuInfoList: this.menuInfo, 174 closeMenu: () => { 175 this.isShow = false; 176 } 177 }) 178 } 179 .alignItems(HorizontalAlign.Center) 180 .justifyContent(FlexAlign.Center) 181 .width(StyleConstants.CONTEXT_MENU_WIDTH) 182 .height(StyleConstants.DEFAULT_40 * this.menuInfo.length + StyleConstants.DEFAULT_8) 183 } 184 185 build() { 186 Column() { 187 AppIcon({ 188 iconSize: mSmartDockStyleConfig.mIconSize, 189 iconId: this.appInfo.appIconId, 190 bundleName: this.appInfo.bundleName, 191 moduleName: this.appInfo.moduleName, 192 icon: ResourceManager.getInstance().getCachedAppIcon(this.appInfo.appIconId, 193 this.appInfo.bundleName, this.appInfo.moduleName), 194 badgeNumber: this.appInfo.badgeNumber 195 }) 196 } 197 .visibility(this.dragItemType === CommonConstants.DRAG_FROM_DOCK && this.smartDragItemInfo.keyName === this.appInfo.keyName ? 198 Visibility.Hidden : Visibility.Visible) 199 .width(mSmartDockStyleConfig.mListItemWidth) 200 .height(mSmartDockStyleConfig.mListItemHeight) 201 .backgroundColor(mSmartDockStyleConfig.mItemBackgroundColor) 202 .borderRadius(mSmartDockStyleConfig.mItemBorderRadius) 203 .parallelGesture( 204 LongPressGesture({ repeat: false }) 205 .onAction((event: GestureEvent) => { 206 Log.showInfo(TAG, 'onAction start'); 207 this.isShow = true; 208 AppStorage.SetOrCreate('isLongPress', true); 209 }) 210 ) 211 .bindPopup(this.isShow, { 212 builder: this.MenuBuilder, 213 placement: Placement.Top, 214 popupColor: Color.White, 215 arrowOffset: AppStorage.Get('deviceType') == CommonConstants.DEFAULT_DEVICE_TYPE ? null : 3 * (mSmartDockStyleConfig.mIconSize / 2) + mSmartDockStyleConfig.mListItemGap, // Avoid the popup offset problem in phone form 216 onStateChange: (e) => { 217 if (!e.isVisible) { 218 this.isShow = false; 219 } 220 AppStorage.SetOrCreate('smartDockShowMenu', e.isVisible) 221 }, 222 autoCancel: true 223 }) 224 .onTouch((event: TouchEvent) => { 225 Log.showInfo(TAG, `onTouch event type: ${event.type}`); 226 if (event.type === CommonConstants.TOUCH_TYPE_UP && AppStorage.Get('isDrag')) { 227 let mIsDragEffectArea = globalThis.SmartDockDragHandler.isDragEffectArea(event.touches[0].screenX, event.touches[0].screenY); 228 if (!mIsDragEffectArea) { 229 AppStorage.SetOrCreate('dragItemInfo', {}); 230 AppStorage.SetOrCreate('selectAppIndex', null); 231 AppStorage.SetOrCreate('isDrag', false); 232 } 233 AppStorage.SetOrCreate('isLongPress', false); 234 } 235 if (AppStorage.Get('isDrag')) { 236 this.isShow = false; 237 } 238 if (event.type === CommonConstants.TOUCH_TYPE_UP && !AppStorage.Get('isDrag') && !this.isShow) { 239 this.onItemClick(event, this.appInfo); 240 } 241 }) 242 .onMouse((event: MouseEvent) => { 243 Log.showInfo(TAG, `onMouse MouseType: ${event.button}`); 244 if (event.button == MouseButton.Right) { 245 event.stopPropagation(); 246 AppStorage.SetOrCreate('selectDesktopAppItem', ''); 247 this.isShow = true; 248 } 249 }) 250 .onDragStart((event: DragEvent, extraParams: string) => { 251 Log.showInfo(TAG, `DragStart`); 252 AppStorage.SetOrCreate('isDrag', true); 253 this.dragItemType = CommonConstants.DRAG_FROM_DOCK; 254 this.smartDragItemInfo = this.appInfo; 255 Log.showInfo(TAG, `smartDragItemInfo: ${JSON.stringify(this.smartDragItemInfo)}`); 256 const selectAppIndex = globalThis.SmartDockDragHandler.getDragItemIndexByCoordinates(event.getX(), event.getY()); 257 AppStorage.SetOrCreate('selectAppIndex', selectAppIndex); 258 return this.dragLayerBuilder(); 259 }) 260 } 261}