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 getListWidth(): number { 49 let residentMaxNum = this.mSmartDockStyleConfig.mMaxDockNum; 50 let width = 0.0; 51 if (AppStorage.Get("deviceType") == CommonConstants.DEFAULT_DEVICE_TYPE) { 52 Log.showDebug(TAG, `getListWidth mDockPadding: ${this.mSmartDockStyleConfig.mDockPadding}, mMaxNum: ${residentMaxNum}`); 53 width = this.mSmartDockStyleConfig.mDockPadding * 2 + residentMaxNum * (this.mSmartDockStyleConfig.mListItemWidth) + (residentMaxNum - 1) * (this.mSmartDockStyleConfig.mListItemGap); 54 Log.showDebug(TAG, `getListWidth width: ${width}`); 55 } else { 56 if (this.appList == null || this.appList.length === 0) { 57 } else { 58 let num = this.appList.length; 59 if (num > residentMaxNum) { 60 num = residentMaxNum; 61 } 62 width = this.mSmartDockStyleConfig.mDockPadding * 2 + num * (this.mSmartDockStyleConfig.mListItemWidth) + (num - 1) * (this.mSmartDockStyleConfig.mListItemGap); 63 } 64 } 65 return width; 66 } 67 68 private onDockListChange() { 69 this.onDockListChangeFunc(); 70 } 71 72 build() { 73 if (this.getListWidth && this.getListWidth() !== 0) { 74 Row() { 75 List({ space: this.appList.length == 0 ? 0 : this.mSmartDockStyleConfig.mListItemGap }) { 76 ForEach(this.appList, (item) => { 77 ListItem() { 78 AppItem({ 79 appInfo: item, 80 buildMenu: this.buildMenu, 81 onItemClick: this.onItemClick 82 }) 83 } 84 }, (item) => JSON.stringify(item)) 85 } 86 .height('100%') 87 .animation({ 88 curve: Curve.Friction 89 }) 90 .listDirection(this.mSmartDockStyleConfig.mListDirection) 91 .editMode(false) 92 } 93 .backgroundColor(this.mSmartDockStyleConfig.mBackgroundColor) 94 .borderRadius(this.mSmartDockStyleConfig.mDockRadius) 95 .backdropBlur(this.mSmartDockStyleConfig.mBackdropBlur) 96 .padding(this.appList.length == 0 ? this.mSmartDockStyleConfig.mDockPadding : this.dockPadding) 97 .width(this.getListWidth()) 98 .height(this.mSmartDockStyleConfig.mDockHeight) 99 .justifyContent(FlexAlign.Center) 100 .onDragEnter((event: DragEvent, extraParams: string) => { 101 Log.showDebug(TAG, `onDragEnter extraParams: ${extraParams}, event: [${event.getX()}, ${event.getY()}]`); 102 }) 103 .onDragMove((event: DragEvent, extraParams: string) => { 104 Log.showDebug(TAG, `onDragMove event: [${event.getX()}, ${event.getY()}]`); 105 }) 106 .onDragLeave((event: DragEvent, extraParams: string) => { 107 Log.showDebug(TAG, `onDragLeave event: [${event.getX()}, ${event.getY()}]`); 108 }) 109 .onDrop((event: DragEvent, extraParams: string) => { 110 Log.showInfo(TAG, `onDrop event: [${event.getX()}, ${event.getY()}]`); 111 const dragResult = globalThis.SmartDockDragHandler.onDragDrop(event.getX(), event.getY()); 112 AppStorage.SetOrCreate('selectAppIndex', null); 113 AppStorage.SetOrCreate('isDrag', false); 114 if (!dragResult) { 115 AppStorage.SetOrCreate('dragItemInfo', {}); 116 } else { 117 // Wait for the UI rendering to end. 118 setTimeout(() => { 119 AppStorage.SetOrCreate('dragItemInfo', {}); 120 }, 50); 121 } 122 }) 123 } 124 } 125} 126 127@Component 128struct AppItem { 129 @StorageLink('dragItemInfo') smartDragItemInfo: any = {}; 130 @StorageLink('dragItemType') dragItemType: number = CommonConstants.DRAG_FROM_DOCK; 131 @State isShow: boolean = false; 132 onItemClick: Function = null; 133 appInfo: DockItemInfo = null; 134 buildMenu: Function = null; 135 private menuInfo; 136 137 @Builder dragLayerBuilder() { 138 Column() { 139 AppIcon({ 140 iconSize: mSmartDockStyleConfig.mIconSize * 1.05, 141 iconId: this.appInfo.appIconId, 142 bundleName: this.appInfo.bundleName, 143 moduleName: this.appInfo.moduleName, 144 icon: ResourceManager.getInstance().getCachedAppIcon(this.appInfo.appIconId, 145 this.appInfo.bundleName, this.appInfo.moduleName), 146 badgeNumber: CommonConstants.BADGE_DISPLAY_HIDE 147 }) 148 } 149 } 150 151 aboutToAppear(): void { 152 this.menuInfo = this.buildMenu(this.appInfo); 153 } 154 155 private getLongPress(): boolean { 156 return AppStorage.Get('isLongPress'); 157 } 158 159 @Builder MenuBuilder() { 160 Column() { 161 AppMenu({ 162 menuInfoList: this.menuInfo, 163 closeMenu: () => { 164 this.isShow = false; 165 } 166 }) 167 } 168 .alignItems(HorizontalAlign.Center) 169 .justifyContent(FlexAlign.Center) 170 .width(StyleConstants.CONTEXT_MENU_WIDTH) 171 .height(StyleConstants.DEFAULT_40 * this.menuInfo.length + StyleConstants.DEFAULT_8) 172 } 173 174 build() { 175 Column() { 176 AppIcon({ 177 iconSize: mSmartDockStyleConfig.mIconSize, 178 iconId: this.appInfo.appIconId, 179 bundleName: this.appInfo.bundleName, 180 moduleName: this.appInfo.moduleName, 181 icon: ResourceManager.getInstance().getCachedAppIcon(this.appInfo.appIconId, 182 this.appInfo.bundleName, this.appInfo.moduleName), 183 badgeNumber: this.appInfo.badgeNumber 184 }) 185 } 186 .visibility(this.dragItemType === CommonConstants.DRAG_FROM_DOCK && this.smartDragItemInfo.keyName === this.appInfo.keyName ? 187 Visibility.Hidden : Visibility.Visible) 188 .width(mSmartDockStyleConfig.mListItemWidth) 189 .height(mSmartDockStyleConfig.mListItemHeight) 190 .backgroundColor(mSmartDockStyleConfig.mItemBackgroundColor) 191 .borderRadius(mSmartDockStyleConfig.mItemBorderRadius) 192 .parallelGesture( 193 LongPressGesture({ repeat: false }) 194 .onAction((event: GestureEvent) => { 195 Log.showInfo(TAG, 'onAction start'); 196 this.isShow = true; 197 AppStorage.SetOrCreate('isLongPress', true); 198 }) 199 ) 200 .bindPopup(this.isShow, { 201 builder: this.MenuBuilder, 202 placement: Placement.Top, 203 popupColor: Color.White, 204 arrowOffset: AppStorage.Get('deviceType') == CommonConstants.DEFAULT_DEVICE_TYPE ? null : 3 * (mSmartDockStyleConfig.mIconSize / 2) + mSmartDockStyleConfig.mListItemGap, // Avoid the popup offset problem in phone form 205 onStateChange: (e) => { 206 if (!e.isVisible) { 207 this.isShow = false; 208 } 209 AppStorage.SetOrCreate('smartDockShowMenu', e.isVisible) 210 }, 211 autoCancel: true 212 }) 213 .onTouch((event: TouchEvent) => { 214 Log.showInfo(TAG, `onTouch event type: ${event.type}`); 215 if (event.type === CommonConstants.TOUCH_TYPE_UP && AppStorage.Get('isDrag')) { 216 let mIsDragEffectArea = globalThis.SmartDockDragHandler.isDragEffectArea(event.touches[0].screenX, event.touches[0].screenY); 217 if (!mIsDragEffectArea) { 218 AppStorage.SetOrCreate('dragItemInfo', {}); 219 AppStorage.SetOrCreate('selectAppIndex', null); 220 AppStorage.SetOrCreate('isDrag', false); 221 } 222 AppStorage.SetOrCreate('isLongPress', false); 223 } 224 if (AppStorage.Get('isDrag')) { 225 this.isShow = false; 226 } 227 if (event.type === CommonConstants.TOUCH_TYPE_UP && !AppStorage.Get('isDrag') && !this.isShow) { 228 this.onItemClick(event, this.appInfo); 229 } 230 }) 231 .onMouse((event: MouseEvent) => { 232 Log.showInfo(TAG, `onMouse MouseType: ${event.button}`); 233 if (event.button == MouseButton.Right) { 234 event.stopPropagation(); 235 AppStorage.SetOrCreate('selectDesktopAppItem', ''); 236 this.isShow = true; 237 } 238 }) 239 .onDragStart((event: DragEvent, extraParams: string) => { 240 Log.showInfo(TAG, `DragStart`); 241 AppStorage.SetOrCreate('isDrag', true); 242 this.dragItemType = CommonConstants.DRAG_FROM_DOCK; 243 this.smartDragItemInfo = this.appInfo; 244 Log.showInfo(TAG, `smartDragItemInfo: ${JSON.stringify(this.smartDragItemInfo)}`); 245 const selectAppIndex = globalThis.SmartDockDragHandler.getDragItemIndexByCoordinates(event.getX(), event.getY()); 246 AppStorage.SetOrCreate('selectAppIndex', selectAppIndex); 247 return this.dragLayerBuilder(); 248 }) 249 } 250}